Limits and budgets
To prevent infinite loops and runaway costs, the runtime enforces several independent limits and budgets that shape how far a run can go.
The rules of limits
- Every run has an overall step ceiling.
- Transfers and successful delegations each have their own separate cap.
- Running out of any ONE of these limits ends the run, not just the overall step count.
- A delegation only counts against its cap if it actually dispatches — a skipped or failed target never consumes budget.
- Cross-agent (agent-to-agent) chains are additionally bounded by a hop-depth ceiling and cycle detection, independent of the step/transfer/delegation caps above. A chain that loops back to an agent already in it, or goes too many hops deep, is stopped.
- A nested cross-agent call also runs with a reduced step budget proportional to how deep the chain already is, so a legal-depth chain still can't multiply total work indefinitely.
Termination reasons
Here is what you might see as a termination reason if a run hits a limit:
| Reason | Meaning |
|---|---|
completed | The run finished normally with a final answer. |
max_steps_exceeded | The run hit its overall step ceiling before reaching a final answer — often a sign the handoff graph needs simplifying, or the step budget is too low for the task. |
transfer_limit_exceeded | The run attempted more transfers than its cap allows — often a sign of an oscillating or looping handoff graph. |
delegation_limit_exceeded | The run attempted more successful delegations than its cap allows. |
delegation_failed | A delegation to another sub-agent could not be completed. |
route_forbidden | A transfer or delegation targeted a sub-agent that isn't in the caller's allowed-targets list — or attempted to TRANSFER to a target that only supports delegation (e.g. an externally-linked/cross-agent sub-agent). |
target_not_found | A transfer or delegation targeted a sub-agent that no longer exists in the agent's current design (e.g. deleted since the graph was last loaded). |
content_filter_blocked | The run was stopped because content-safety filtering rejected a message. |
remote_dispatch_failed | A call to an externally-linked agent (a cross-org/agent-to-agent hop) failed even after retrying. |
agent_cycle_detected | A chain of agent-to-agent calls looped back to an agent already in the chain, and was stopped to prevent an infinite loop. |
max_agent_hops_exceeded | A chain of agent-to-agent calls went deeper than the allowed hop limit. |
ambiguous_handoff | The active sub-agent's routing intent couldn't be resolved even after an automatic self-correction retry, so the run terminated rather than guessing indefinitely. |
orchestration_failed | An unexpected internal error stopped the run outside any of the other specific cases listed here. |
execution_canceled | The run was canceled (e.g. a client disconnected, or an operator stopped it) rather than failing or completing. |
Authoring implications
If a run keeps hitting a limit, check the routing timeline for a repeating handoff pattern first — most limit-exceeded terminations trace back to a graph that loops or bounces rather than the caps themselves being too low.
Common Pitfall: Assuming any two of the step cap, transfer cap, delegation cap, or hop-depth cap share the same budget. They don't; each is tracked and enforced independently.