Skip to main content

Troubleshooting: agent runtime errors

An agent run returns a non-2xx envelope, an SSE stream aborts with an error event, or a conversation shows a failed turn in the Live tab. The error.code in the response tells you which gate fired. This page covers the six codes the agent runtime throws, in the order you will meet them. The full list of platform codes lives in the error reference; this page gives you the fix for each agent code. A typical envelope looks like this — the code is the stable identifier you key on, never the message text:

Decision table — agent error → fix

Do not retry the deterministic codes

Three of these codes re-fail deterministically — a retry re-runs the same gate and returns the same code:
  • AGENT_NOT_CONFIGURED — the prompt is still missing until you write one.
  • INVALID_MODEL — the model id is still illegal until you pick a supported one.
  • A capped or gated run (cost caps, guardrails) — same input, same gate.
Retry only the transient ones: LLM_PROVIDER_ERROR (provider blip), AGENT_RESPONSE_INVALID (occasionally), and AGENT_EXECUTION_TIMEOUT after you have removed the loop cause — otherwise the retry burns the 30-second ceiling again. Live-stream clients key on the same sanitised code set: the SSE path maps upstream failures to stable machine codes (LLM_RATE_LIMITED, LLM_OVERLOADED, AGENT_EXECUTION_TIMEOUT, …) so your client can branch on code, not on a message string.

Distinguish timeout from runaway loops

AGENT_EXECUTION_TIMEOUT has two very different causes and they pair with different fixes:
  • A genuinely slow agent — a deep-research prompt with a legal 30 s budget. Fix: set config.latency_budget.turn_ms (up to 180 000 ms) on the agent and retry.
  • A runaway tool loop — the agent chains the same tool until the ceiling trips. Fix: inspect the run in the Live tab, find the repeating tool call, and correct the tool or the prompt that re-invokes it. Raising the ceiling hides the loop rather than fixing it; the parallel tool_loop_limit cap exists for that case.

Delete and archive guards

A DELETE /agents/:id or a write against an archived agent fails with one of the codes below. These are deterministic gates, not runtime faults — the runbook is short: clear the reference that blocked you, then repeat the call. Two adjacent codes are documented where they belong rather than re-explained here:

Child rows to clear first

Delete refuses while any of these still point at the agent. Walk them in order:
  1. Active conversations — the delete pre-check returns a 409 while the agent owns active conversations. Let them finish or close them.
  2. Squads where the agent is the classifier — the hard stop that raises AGENT_REFERENCED_BY_SQUAD. Re-point the classifier slot or delete the squad.
  3. Squads where the agent is the fallback — the fallback slot would auto-null on delete, but the pre-check reports it ahead of time so you see the full impact before confirming.
  4. Anything else referencing the agent — if a row is created in the gap between the pre-check and the delete, the backstop raises AGENT_REFERENCED_BY_CHILD_ROWS. Clear the new reference and retry.

Error samples

AGENT_REFERENCED_BY_SQUAD — the message lists the blocking squads:
AGENT_REFERENCED_BY_CHILD_ROWS — the race-time backstop, same 409:
AGENT_ARCHIVED:
AGENT_REQUIRED:

Do not force it through

Every one of these guards is deterministic. A force-delete attempt — sending the same body with an added force: true, or issuing the raw delete from a client — returns the identical 409/422 on every retry; there is no force flag the API honors. Clearing the references is the only path through. Escalate only if the guard keeps firing after the response’s own list is empty — e.g. AGENT_REFERENCED_BY_SQUAD still 409s when every squad it named has been re-pointed. That indicates a stale pre-check, not operator error; include the request_id from meta, the agent id, and the squad ids you detached.

When to escalate

Escalate to support when:
  • The same agent returns AGENT_ERROR with an empty or opaque message and you have ruled out the table above.
  • LLM_PROVIDER_ERROR persists after the status page reports all operational.
  • AGENT_EXECUTION_TIMEOUT fires on a turn with no tool calls at all — that should not reach the ceiling.
Include the request_id from the meta block of the failing response, the agent id, and the conversation id. The request id threads through the chat, stream, and invoke paths, so support can pull the executor-side trace without a back-and-forth.

See also