Version: Current
Historical release snapshot. These docs are frozen. Read current docs.
Diagnose a 502
A 502 means every candidate seat failed. The gateway does not retry the same
deployment, so the request has a small, ordered list of reasons.
1. Read the code, not the message
Section titled “1. Read the code, not the message”curl -sS -o /tmp/reply.json -w '%{http_code}\n' http://127.0.0.1:4020/v1/chat/completions \ -H "Authorization: Bearer $ACUMEN_KEY" -H 'Content-Type: application/json' \ -d '{"model":"cheap","messages":[{"role":"user","content":"ping"}]}'jq -r '.code // .error.code // .error.type' /tmp/reply.jsonupstream_error is the vendors; upstream_empty is a vendor that answered
200 with no content; model_no_eligible_seat is a routing failure before any
vendor was called. The full set is in the error reference.
2. Separate routing from vendor failure
Section titled “2. Separate routing from vendor failure”model_no_eligible_seat and model_not_found are decided before a call. If you
see either, no vendor was contacted and the seat list is the problem. Check
seat_health for a cooling row:
SELECT provider, account, model, cooling_until, consecutive_failures, last_error_code FROM seat_health WHERE cooling_until > now() ORDER BY cooling_until DESC;3. Check the attempt ledger
Section titled “3. Check the attempt ledger”Every seat attempt is one row in attempt (internal/store/migrations/0002_ledger.sql:25),
joined to its request. The newest failures for one request answer “who did we
try, in what order”:
SELECT a.seat_id, a.status, a.error_code, a.latency_ms FROM attempt a WHERE a.request_id = $1 ORDER BY a.id;4. If it is one seat
Section titled “4. If it is one seat”A seat that fails repeatedly cools down rather than disappearing. Do not delete the row: add a provider again with a corrected key, or retire the offer, and the cooldown resolves on its own.
5. If it is every seat
Section titled “5. If it is every seat”That is an estate problem, not a request problem: check the provider’s status
page and the gateway’s own metrics before changing anything. A wrong key on one
seat cannot produce a fleet-wide 502; the routing has other candidates. First
separate the two: the status page probes the gateway at
GET /readyz, so an ai row that is up means the estate answered and every
upstream failed.