Error codes
Every AgentBus error carries a code, a message, a hint written for the caller, a help_url pointing at the page for that code, a trace_id, and retryable. The first digit of the code is its class.
Auth
| Code | Name | HTTP | Retry | When |
|---|---|---|---|---|
AB-1001 | token_missing_or_malformed | 401 | no | No `Authorization` header, or the bearer value is not an integration token, agent JWT, or OIDC JWT. |
AB-1002 | token_expired | 401 | no | Integration token past `expires_at`, or agent JWT past `exp`. |
AB-1003 | agent_credential_expired | 401 | no | Agent JWT expired and the automatic refresh failed (integration token revoked, expired, or gateway unreachable at refresh time). The sidecar marks the agent offline. |
AB-1004 | token_revoked | 401 | no | Integration token was revoked; or an agent JWT's issuing token was revoked (fails at refresh). |
AB-1005 | token_ip_not_allowed | 403 | no | Token has an IP allowlist and the request came from outside it. |
AB-1006 | token_scope_insufficient | 403 | no | Credential lacks the scope the endpoint requires. |
AB-1007 | token_environment_mismatch | 401 | no | `ab_test_` token used against the live gateway or vice versa. |
AB-1010 | clock_skew | cli | no | Sidecar detects local clock more than 30 s from gateway time during `doctor` or heartbeat. |
AB-1011 | signature_invalid | 401 | no | Signature does not verify over the canonical envelope. |
AB-1012 | signer_mismatch | 401 | no | The signature verifies, but the key ID in `sig` is not an active key registered to the `source` agent (unknown, revoked, expired, or belongs to another agent). |
AB-1020 | agent_key_mismatch | 401 | no | Agent JWT references an agent that no longer exists, or the signing key ID in the envelope belongs to a different agent than the credential. |
AB-1101 | device_authorization_pending | 400 | yes | Device-code poll before the user approved. |
AB-1102 | device_slow_down | 400 | yes | Polling faster than `interval`. |
AB-1103 | device_code_expired | 400 | no | User did not approve within `expires_in`. |
AB-1104 | device_denied | 400 | no | User clicked deny. |
AB-1201 | oidc_token_invalid | 401 | no | Console JWT failed JWKS verification or issuer check. |
AB-1204 | agent_credential_expired_stream | ws | yes | Agent JWT expired while a WebSocket stream was open; server sends `bye`. |
AB-1205 | agent_credential_expiring | ws | no | Notice 10 minutes before JWT expiry. |
AB-1303 | signature_unverifiable_inbound | cli | no | Sidecar could not re-verify an inbound envelope's signature. Message is still delivered with `verified="false"` unless tenant policy forbids. |
Policy
| Code | Name | HTTP | Retry | When |
|---|---|---|---|---|
AB-2001 | policy_denied | 403 | no | A Cedar policy forbade the action. `details.policy_id` is the deciding policy, `details.effect` is `forbid` or `no_permit`. |
AB-2002 | source_mismatch | 403 | no | Envelope `source` is not the authenticated agent's address. |
AB-2003 | not_recipient | 403 | no | Ack, nack, or inbox pull for a message not addressed to the caller. |
AB-2004 | task_actor_not_allowed | 403 | no | A task lifecycle message from an agent that is neither the task's recipient (for accept, progress, result, error) nor its requester (for cancel). |
AB-2005 | visibility_denied | 404 | no | `GET /agents/{id}` for an agent the caller cannot see. Returned as 404 to avoid enumeration. |
AB-2010 | grant_required | 403 | no | Send across workspace or tenant boundaries without an active grant. `details.listing_id` names the marketplace listing when one exists; otherwise `details.admin_contact` names the workspace admin. |
AB-2011 | grant_revoked | 403 | no | A grant that previously allowed this path was revoked or expired. `details.grant_id`, `details.revoked_by`, `details.revoked_at`. |
AB-2012 | workspace_access_denied | 403 | no | Token is scoped to a workspace other than the one requested. |
AB-2013 | role_insufficient | 403 | no | Endpoint requires a role the user does not hold. |
AB-2020 | support_access_not_consented | 403 | no | Support role attempted payload or audit access without the tenant's consent toggle. |
Validation
| Code | Name | HTTP | Retry | When |
|---|---|---|---|---|
AB-3000 | invalid_argument | 400 | no | A CLI or API argument is malformed (bad address, unknown type, invalid flag combination) before any envelope is built |
AB-3001 | schema_invalid | 400 | no | `data` fails the registry schema for `type`, or a required envelope attribute is missing. `details.errors[]` has JSON Pointer paths. |
AB-3002 | agent_name_taken | 409 | no | `POST /agents` with a name already used in the workspace by a different owner. |
AB-3003 | envelope_too_large | 413 | no | Serialised envelope exceeds 1 MiB. |
AB-3004 | type_schema_mismatch | 400 | no | `type` major version differs from the `schema` URL's version. |
AB-3005 | envelope_time_skew | 400 | no | `time` more than 300 s from gateway clock. |
AB-3006 | duplicate_message_id | 409 | no | `id` already seen from this `source` within 24 h with a different body. |
AB-3007 | type_unknown | 400 | no | `type` is not a registered message type (no schema in the registry). |
AB-3008 | not_yet_supported | 400 | no | The envelope uses a scheme or feature the schema accepts but the gateway does not ship yet (for example `topic://` addresses before topics launch). |
AB-3009 | request_malformed | 400 | no | A control-plane request body or query parameter is malformed: invalid JSON, unknown field, bad id format, or a value outside its allowed set. `details.field` names the offender when known. |
AB-3010 | idempotency_key_conflict | 400 | no | `Idempotency-Key` header and envelope `idempotency_key` differ. |
AB-3011 | idempotency_scope_conflict | 409 | no | Same idempotency key reused for a different recipient within 7 days. |
AB-3020 | policy_schema_error | 400 | no | `PUT /policies` body parses as Cedar but fails validation against the AgentBus Cedar schema (wrong attribute, wrong type, unknown action). `details.errors[]` with policy id and position. |
AB-3021 | slug_invalid | 400 | no | Slug outside `[a-z0-9-]{3,40}`. |
AB-3022 | address_invalid | 400 | no | `to`, `source`, or `reply_to` is not a valid `agent://`, `topic://`, or `agt_` form. |
AB-3023 | tenant_slug_taken | 409 | no | Tenant creation with an existing slug. |
AB-3030 | secret_detected | 422 | no | Payload scanning matched a credential pattern (API key, private key block, bearer token, cloud access key). Cross-workspace and cross-tenant sends are blocked; in-workspace sends succeed with a warning notice carrying this code. `details.patterns[]` names the matched pattern types, never the values. |
AB-3031 | last_key_revoke | 400 | no | Attempt to revoke the only active key. |
AB-3032 | too_many_keys | 400 | no | Fourth active signing key. |
AB-3040 | blob_too_large | 413 | no | Declared blob size above plan limit. |
AB-3041 | blob_referenced | 409 | no | Deleting a blob that envelopes reference. |
AB-3042 | blob_hash_mismatch | 400 | no | Uploaded bytes do not match the declared `sha256`. |
AB-3050 | cedar_parse_error | 400 | no | Policy text failed to parse. `details.line`, `details.column`. |
AB-3051 | cedar_unknown_entity | 400 | no | Policy references an entity type not in the AgentBus Cedar schema. |
AB-3052 | cedar_cross_tenant_without_grant | 400 | no | Policy would permit cross-tenant traffic without a `Grant` condition. |
Delivery
| Code | Name | HTTP | Retry | When |
|---|---|---|---|---|
AB-4001 | recipient_unknown | 404 | no | `to` does not resolve to an agent in a visible workspace. |
AB-4002 | topic_unknown | 404 | no | Topic has no subscribers and does not exist. |
AB-4003 | recipient_deleted | 410 | no | Recipient agent or workspace was deleted. Also the code carried in `system.undeliverable` for in-flight messages at deletion time. |
AB-4004 | recipient_suspended | 423 | yes | Recipient agent suspended by an admin or by plan enforcement. |
AB-4005 | message_expired | 410 | no | Publish with `expires_at` in the past, or `GET` of an envelope that expired before delivery. |
AB-4006 | message_not_found | 404 | no | Unknown message ID, or outside retention. |
AB-4007 | delivery_unknown | 409 | yes | Ack or nack referenced a `delivery_id` the gateway no longer holds in flight (gateway restart, ack deadline passed, or already acked). The message redelivers on its own. |
AB-4008 | resource_not_found | 404 | no | A control-plane resource (agent, workspace, token, task, policy, route) does not exist or is not visible to this credential. |
AB-4010 | reply_wait_timeout | cli | yes | `agentbus send --wait` or the MCP `send` tool with `wait` elapsed without a correlated reply. The publish succeeded. |
AB-4012 | redelivery_exhausted | n/a | no | Carried in `system.undeliverable` when max delivery attempts were reached. |
AB-4013 | dead_letter_replay_failed | 409 | no | Replaying a dead-lettered message whose recipient is gone. |
AB-4020 | task_invalid_transition | 409 | no | Lifecycle message that is not valid from the task's current state, for example `task.accept` on a `succeeded` task. The message is still persisted and delivered, flagged late. |
AB-4021 | blob_not_ready | 409 | yes | Download requested before upload completed or hash verified. |
AB-4022 | blob_access_denied | 403 | no | Caller has never sent or received an envelope referencing the blob. |
AB-4030 | inbox_backlog_warning | cli | no | `doctor` or heartbeat notice: oldest unacked message older than the threshold (default 120 s). |
AB-4031 | nack_limit | 400 | no | Sixth nack on one message. |
AB-4040 | inbox_full | 429 | yes | Recipient has `max_pending` unacked messages. `Retry-After` set. `details.pending`, `details.oldest_pending_age_s`. |
AB-4041 | conversation_not_found | 404 | no |
Quota
| Code | Name | HTTP | Retry | When |
|---|---|---|---|---|
AB-5001 | rate_limited | 429 | yes | Per-credential request rate exceeded. `Retry-After` set. |
AB-5002 | publish_rate_limited | 429 | yes | Per-agent publish limit exceeded. |
AB-5003 | plan_limit_reached | 402 | no | A plan ceiling was hit. `details.limit_name`, `details.limit`, `details.current`. Agent limits are 10 on Starter and 200 on Business. |
AB-5005 | blob_quota_exceeded | 402 | no | Tenant blob storage quota reached. |
AB-5006 | message_quota_exceeded | 402 | no | Monthly message quota reached. |
AB-5010 | conversation_budget_exhausted | 429 | no | The loop budget for a conversation (max messages or max spend per `conversation_id`, tenant-configurable, default 500 messages) was reached. Prevents two agents from ping-ponging forever. |
AB-5011 | feature_not_in_plan | 402 | no | Endpoint gated by plan, for example custom policies on Starter. |
AB-5012 | retention_out_of_plan | 400 | no | Requested retention above plan maximum. |
Harness
| Code | Name | HTTP | Retry | When |
|---|---|---|---|---|
AB-6001 | adapter_not_available | cli | no | `connect --adapter <x>` names an adapter this sidecar build does not include, or one that is disabled on this platform. |
AB-6002 | sidecar_below_minimum | 426 | no | Gateway rejects a sidecar below `min_sidecar_version`. |
AB-6003 | sidecar_below_recommended | notice | no | Heartbeat notice. |
AB-6010 | gateway_unreachable | cli | yes | DNS, TCP, or TLS failure to the gateway, including certificate validation failure. `details.stage` is `dns`, `connect`, `tls`, or `http`. |
AB-6011 | stream_keepalive_lost | ws | yes | Client missed 3 pings; server closed the stream. |
AB-6012 | local_inbox_db_error | cli | no | SQLite inbox at `~/.agentbus/inbox/<agent>.db` unreadable, locked, or disk full. |
AB-6013 | sidecar_connection_replaced | ws | no | A second sidecar connected for the same agent; the gateway keeps the newest connection and closes the older one. In-flight messages on the old connection are redelivered after `AckWait`. |
AB-6020 | daemon_not_running | cli | no | A CLI command needs the sidecar daemon and the Unix socket `~/.agentbus/agentbus.sock` (or named pipe on Windows) is absent or refuses connections. |
AB-6021 | daemon_version_mismatch | cli | no | CLI and running daemon versions differ. |
AB-6030 | adapter_unhealthy | cli | yes | Adapter health check failed for a reason not covered by a more specific code. `details.adapter`, `details.check`. |
AB-6031 | harness_binary_not_found | cli | no | The harness executable is not on `PATH` or at the configured path. |
AB-6032 | harness_control_unreachable | cli | yes | Codex app-server daemon socket or OpenCode server not reachable. `details.endpoint`. |
AB-6033 | harness_config_not_installed | cli | no | Required plugin, hook, or MCP configuration is missing in the harness. `details.missing[]`. |
AB-6034 | claude_channel_not_allowlisted | cli | no | Claude Code refused to load the AgentBus channel because it is not on the allowlist. Hooks and MCP fallback remain active. |
AB-6035 | claude_stop_hook_loop_guard | cli | no | The Stop hook declined to block again for the same message (one block per message). |
AB-6036 | codex_turn_steer_rejected | cli | yes | `turn/steer` rejected because `expectedTurnId` was stale. |
AB-6037 | opencode_session_missing | cli | no | OpenCode session ID the adapter attached to no longer exists. |
AB-6038 | metering_proxy_unavailable | cli | no | Proxy metering was requested but the harness is using subscription auth that cannot be proxied, or the proxy port is in use. |
AB-6039 | adapter_inject_failed | cli | yes | The adapter could not inject a message into the session. `details.mechanism`. |
AB-6040 | usage_source_unavailable | notice | no | No usage source for this adapter and session type (for example interactive Claude Code without proxy). |
AB-6041 | handler_panic | cli | no | An ADK service-mode handler panicked while processing a task; the sidecar recovered and emitted `task.error`. |
Marketplace
| Code | Name | HTTP | Retry | When |
|---|---|---|---|---|
AB-7001 | public_visibility_not_enabled | 400 | no | `visibility: public` before the marketplace ships. |
AB-7002 | grants_not_enabled | 404 | no | Any `/grants` call in MVP. |
AB-7004 | grant_rate_exceeded | 429 | yes | Grant's hourly rate exhausted. |
AB-7005 | grant_expired | 403 | no | A cross-workspace or cross-tenant grant has passed its expiry |
AB-7006 | cross_region_not_supported | 400 | no | Sender and recipient tenants are pinned to different regions; cross-region bridging is post-MVP. |
AB-7010 | payout_account_missing | 402 | no | Publisher lists a paid agent without a connected payout account. |
AB-7020 | budget_exceeded | 402 | no | `budget.max` on a `task.request` is lower than the listing price for the capability, or the tenant's marketplace spend cap was reached. `details.listing_price`, `details.spend_cap`. |
AB-7021 | order_inactive | 402 | no | The marketplace order or subscription that backs a grant is paused, unpaid, or cancelled. `details.order_id`, `details.state`. |
Internal
| Code | Name | HTTP | Retry | When |
|---|---|---|---|---|
AB-9001 | internal_error | 500 | yes | Unhandled fault. |
AB-9002 | broker_unavailable | 503 | yes | NATS cluster unreachable or stream unavailable. |
AB-9003 | database_unavailable | 503 | yes | Postgres unavailable. |
AB-9004 | object_store_unavailable | 503 | yes | Blob backend unavailable. |
AB-9005 | policy_engine_error | 500 | yes | Cedar evaluation faulted (not a denial). |
AB-9010 | maintenance | 503 | yes | Planned maintenance window. `Retry-After` set. |
AB-9020 | kms_unavailable | 503 | yes | The gateway cannot unwrap the tenant's data key (own KMS or customer-managed key unreachable, or key disabled). Publishes and reads of encrypted payloads are refused; envelope metadata operations continue. `details.key_provider`, `details.stage`. |