Skip to main content
Every BeeOS OpenAPI response that isn’t a 2xx (and every SSE event: error / event: done with is_error: true) carries a stable machine-readable code field. This page is the single source of truth for that code; the wire envelopes only differ in shape, not in vocabulary. The complete catalogue is generated from backend/shared/types/apierror/ which is shared across Gateway, Agent Gateway, A2A Gateway, MCP Gateway, OpenAPI Gateway and the internal services. Codes in this table are public contract — they will not change shape during the 1.x line. Adding new codes is a minor version bump; renaming or removing a code is a major version bump.

How errors are encoded

Blocking JSON response (any 4xx / 5xx)

The HTTP status line carries the same information as error.code (see the table below). The type field is the RFC 9457 problem-type (“api_error” / “invalid_request_error” / “authentication_error” / “permission_error” / “rate_limit_error” / “not_found_error” / “conflict_error” / “validation_error”); SDKs typically key on code rather than type.

SSE event: error frame (streaming invoke + task events)

The code / status_code are exactly what the blocking JSON path would have returned for the same condition. See Streaming (P1-F, planned) for full SSE frame semantics.

SSE event: done terminal frame

When a stream ends in error, done.code mirrors the error frame’s code so a client that only consumes done is still able to dispatch:
There is one streaming-specific code that never appears in blocking JSON:
  • agent_reply_error — the agent itself returned an in-band error message (agent_reply with is_error: true). The HTTP / SSE transport succeeded; the agent reported a domain-level failure. done.text carries the agent’s error text.

Code catalogue

4xx — client errors

5xx — server errors

Streaming-only codes


Mapping chatinvoke sentinels → wire codes

The OpenAPI Gateway’s invokeErrToAPIError (handlers_agents.go) collapses the pkg/chatinvoke sentinel errors into wire-level codes:
Note: pre-P0-B versions of this contract used distinct code values task_rejected / agent_busy / agent_unavailable in client-facing docs. Those were never the wire codes — the actual wire has always been conflict / agent_service_unavailable with the discriminator in message. SDK clients must key on the code values in this table, not on the older doc values.

TypeScript SDK recipe

Go SDK recipe


See also