Workflow runs: limits and failures

A workflow run executes a coordination script that fans work out across helper agents and returns one value. This page is the reference for writing and debugging such scripts: how a run ends, what its result carries, the limits it works within, and the failures it can report. For what a workflow is and how a run starts, see The workflow tool.

How a run ends

A run settles once, with exactly one stop reason:

Stop reasonWhat it means
completedThe script finished and its return value came back.
cancelledThe run was stopped, with a reason where one was given.
errorThe run failed; the error says how.

How agent calls end

The limits a run works within

LimitValueWhat it bounds
Agent concurrencyResolved from the machine's available CPU parallelismHow many agent calls run at the same time
Total agent calls1,000 per runHow many calls one run may start
Items per call4,096How many items one fan-out call may take
Initial synchronous slice5,000 msThe stretch of a script that runs before it first yields
Overall deadlineNoneA run has no elapsed-time limit
Note

The caps are cooperative backstops for runaway work, not security quotas.

The failures that end a run

Each failure below stops the run and is reported in its error.

Stopping a run

What a run records

A top-level run writes four records into the chat's log as it goes: the run's start, an agent's start and end for each call, and the run's end.

Questions, answered

Why did my workflow run fail?

The run's error names the failure: a script that does not parse, a script whose initial synchronous slice timed out, a return value that is not plain JSON, meta that fails validation, a call that could not start or whose result could not come back, a cap reached, or an up-front validation refusal. A stopped or failed run never presents partial output as a successful result.

Is there a deadline for a whole run?

No. A run has no overall elapsed-time limit: it keeps going until it completes, fails or is stopped. The one timed stretch is the script's initial synchronous slice, bounded at 5,000 ms; work that yields, such as agent calls, is not under that bound.

What does the total agent cap message mean?

The run started more agent calls than its total-agent ceiling allows, 1,000 by default. It is a backstop against runaway loops: the run ends, and the message says the limit can be raised if the scale is intentional. A run can come with a lower ceiling of its own, but nothing raises one above the engine's.

Why did an agent call come back empty instead of failing the run?

A child that failed on its own, including one that missed the structured result you asked for, hands back null; the script decides what to do with it. Only faults around the call itself, a provider that cannot start the child or a child result that cannot come back, end the run.

Why was my return value rejected as not plain JSON?

Values that cannot cross back are refused: non-finite numbers, bigints, functions, symbols, an undefined inside a container, circular references, sparse arrays and objects with exotic prototypes. Return plain objects, arrays and scalars.

Why did I get "Script execution timed out"?

The script's initial synchronous slice, the part before it first yields, ran past 5,000 ms; a loop that never yields trips this bound. Progress already sent is kept. Long stretches belong behind awaited work such as agent calls, so the script leaves its opening slice.

What happens to agent calls still running when a run is stopped?

They end as cancelled, one ending per started call. A child that only becomes ready after the stop is disposed without making a request, and the run settles only after the script and its children are cleaned up.

Can a run's result change after it settles?

No. It settles once, with the first accepted outcome; a stop after that does not rewrite it, and the result never rejects.

What is recorded for a run in the chat's log?

Four records: the run's start, each agent's start and end, and the run's end. They are observational: they stay out of the conversation and never reach a model request. An agent's start is recorded before the child's first request, and the run's end only after the result and the cleanup have settled.

Can I raise a run's limits?

The ceilings come from the engine's configuration in the deployment; a run can lower its own total-agent ceiling, but nothing raises a ceiling above the engine's. Concurrency is resolved from the machine's available CPU parallelism by default.