2 min read · 454 words
API — Errors
Two error body shapes cover the whole API: a detail string for domain errors, and FastAPI's detail array for validation. This page tells clients exactly what to do with each code.
Body shapes
json
{ "detail": "This agent does not have email_analyzer tool enabled" }A client that must render one message can use the frontend's normalization rule: string detail → show as-is; array detail → join the msg fields (API Proxy).
Code-by-code
| Code | Emitted when | Client should |
|---|---|---|
| 400 | bad upload (type/encoding/empty), invalid task status, delete-without-force | fix the request; the message is specific and user-showable |
| 403 | agent lacks the required tool | enable the tool on the agent (recreate with the right enabled_tools) or use a different agent — retrying is pointless |
| 404 | agent / task / workflow-run ID doesn't exist | treat as stale reference; refresh your list |
| 422 | body fails Pydantic validation | fix field-level issues from loc/msg |
| 500 | LLM/embedding failure, JSON-parse failure, unexpected exception | inspect detail (contains the exception text); check the failed ToolCall / run records; retrying may succeed for transient OpenAI errors — the server itself never retries |
| 502 | (frontend proxy only) backend unreachable | start/point the backend; not emitted by FastAPI itself |
The 200s that carry failure
Two success responses require client-side judgment:
- Chat fallback —
POST .../chatreturns200withassistant_response = "Sorry, I could not generate a response right now."when the LLM failed. Detect via the string or by checking the run'sstatus(why). - RAG refusal —
POST .../documents/askreturns200with the fixed refusal string; checkretrieval_evaluation.has_answer(semantics).
Error observability
Server-side failures in tools/workflows always leave evidence before the 500 goes out: a failed ToolCall (with error_message), plus — for workflows — a failed run and a workflow_error step. Diagnose from the records, not just the response:
bash
curl http://localhost:8001/agents/1/tool-calls | jq '[.[] | select(.success=="false")]'
curl http://localhost:8001/agents/1/workflow-runs | jq '[.[] | select(.status=="failed")]'Caveats for client authors
detailon 500s contains raw exception text — useful in dev, do not render to end users verbatim.- There are no error codes (machine-readable enums), only messages — match on status first, message second.
- No rate-limit (429) or auth (401/403-auth) semantics exist yet; today's 403 means tool gating specifically.
Related pages
- Error Handling — the server-side philosophy
- Troubleshooting — symptom-first diagnosis