# OBEP Error Taxonomy

Stable error codes carried on `status` messages (`phase: "error"`, `code`). The
canonical source is [`ERROR_CODES`](../obep/protocol/src/wire.ts) in
`@obep/protocol`. Consumers MUST tolerate unknown codes (forward-compatible).

| Code | Meaning | Typical cause |
|---|---|---|
| `no_binding` | No `(tenantId, userId)` binding to route to. | Task targets an unpaired user, or no extension connected. |
| `permission_denied` | Action/credential/capture outside the playbook boundary. | Action not in `allowedActions`; credentialKey not allowed. |
| `element_not_found` | Referenced element/selector absent. | Page changed; selector stale. |
| `navigation_blocked` | Domain not allowed, or a blocked sensitive surface. | Target outside `allowedDomains`; unacknowledged sensitive surface. |
| `credential_not_found` | Vault locked or no entry for the key. | Vault not unlocked; key never stored. |
| `timeout` | Operation exceeded its budget. | Slow page load / wait. |
| `bad_message` | Malformed/non-conformant wire message. | Invalid JSON; unknown shape. |
| `playbook_invalid` | Signature/hash verification failed or tenant mismatch. | Tampered playbook; wrong key; cross-tenant playbook. |
| `consent_required` | Unknown/widened playbook needs fresh consent (TOFU). | First use, or scope widened vs the approved version. |
| `halted` | Deterministic step couldn't proceed and `fallback: "halt"`. | High-assurance flow chose not to improvise. |
| `unauthorized` | Bad/revoked API key, or unverifiable task token. | Wrong API key; forged/expired task token. |
| `rate_limited` | Tenant exceeded its rate limit. | Too many task starts in the window. |
| `pairing_failed` | Invalid/expired/used pairing material. | Replayed pairing token; bad assertion. |
| `internal` | Unexpected relay/extension error. | Bug; peer disconnected mid-task. |
