Errors
Available
Envelope
Section titled “Envelope”{ "error": { "code": "rate_limited", "message": "request limit exceeded", "retryable": false }}The field is code, not type.
retryable is the only correct signal
Section titled “retryable is the only correct signal”except APIError as e: if e.retryable: ... # retrying is SAFE else: ... # retrying will NOT fix it⛔ Do not decide from the HTTP status. A 503 is sometimes retryable and
sometimes not — that depends on connector semantics, which only the
platform knows.
Main codes
Section titled “Main codes”| Code | HTTP | retryable |
What to do |
|---|---|---|---|
unauthorized |
401 | ❌ | Check your key |
forbidden |
403 | ❌ | No permission — grant it in the console |
not_found |
404 | ❌ | Check the identifier |
invalid_request |
400 | ❌ | Malformed request |
duplicate_intent |
409 | ❌ | ⚠ This is protection — wait |
duplicate_intent_verified |
409 | ❌ | ✅ Already done |
knowledge_conflict_hold |
409 | ❌ | Held for human review |
rate_limited |
429 | ⚠ | Respect Retry-After |
ledger_unavailable |
503 | ✅ | The ledger did not respond — the action did not run |
timeout |
504 | ⛔ | ⚠ Outcome unknown — see below |
Full list: error codes.
⚠ Timeout is a special case
Section titled “⚠ Timeout is a special case”timeout → the action MAY have happenedHere the retryable question is the wrong question. The correct
behaviour:
- Do not resend.
- Fetch the execution — the operation will be
UNKNOWN. - Wait for reconciliation to determine the final state.
Why ledger_unavailable is safe
Section titled “Why ledger_unavailable is safe”503 ledger_unavailable means the operation ledger did not respond. In
that case the action was never performed: the platform refuses to run
a write without duplicate protection (fail-closed).
That is why this error is retryable: true — retrying is safe.
Asking for help
Section titled “Asking for help”Include the execution_id and request_id:
except APIError as e: log.error("davirix", request_id=e.request_id, code=e.code)⛔ Do not send conversation text — we do not need it, and under zero-retention it is not stored anyway.