Skip to main content
The client evaluation API never throws. Abnormal execution returns the caller-supplied default with reason: ERROR and an error kind. If a typed getter raised, that is a bug. First diagnostic step: read details, not just the value.
errorKind (also copied onto metadata['fireweave.errorKind']) is the Fireweave kind. Use it to tell NotReady from AlreadyClosed — both still carry the historical OpenFeature code PROVIDER_NOT_READY on errorCode. The bundled OpenFeature provider is gone; the codes remain on the Decision because spec/errors.schema.json pins them.

15 kinds

Canonical kinds from contracts/errors.md / spec/errors.schema.json. Messages are secret-redacted (no API keys, bearer tokens, or FW_PROJECT_API_KEY values). * MalformedResponse is permanent for a given response; a later request may succeed. Adapters must not invent flag values. InvalidContext subtype: missing required targetingKey → TARGETING_KEY_MISSING. All other context violations (type, reserved keys, size/depth/count bounds) → INVALID_CONTEXT. Init is the exception to never-throw: bad mode or credentials raise Configuration at boot. See Lifecycle.

Language surfaces

Reasons that are not errors

UnsupportedCapability

Expected in v1 for:
  1. InMemoryAdapter.registerTarget — the fixture adapter does not persist registration. Use mode: 'local' when the test needs to assert it.
  2. A custom adapter that does not implement register.
The guardrails stub is gone. client.guardrails is a compile/import error, not an UnsupportedCapability result. Guardrails are platform-managed; the SDK has no guardrails API.

Next

Troubleshooting

Default values, auth, STALE

Control points

Never-throw reads and Decision reasons
Last modified on September 11, 2026