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 fromcontracts/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:
InMemoryAdapter.registerTarget— the fixture adapter does not persist registration. Usemode: 'local'when the test needs to assert it.- A custom adapter that does not implement register.
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

