no_output and
step_limit, both trace back to something the prompt did or did not say.
Prompting an agent covers the conversational half and
deliberately does not cover this.
You do not write the ending
When a run starts, the task gains a generated tool namedsubmit_result, built
from your output fields, and a generated paragraph appended to your prompt
that starts:
null rather than omitting or
guessing, and then lists each field with its type and its description. The tool
and the paragraph are both written for you, on every run, however your prompt is
written. The full shape is in inputs and output.
So your prompt carries the work, not the exit. Everything about how the run
ends is handled. Everything about what the run is for, where to look, and what
counts as a good answer is yours.
The shape that works
Five things, in this order.
The last one is the section people leave out, and it is the one that costs
steps. A model with no permission to fail keeps searching, and a task that keeps
searching runs out of rounds.
Here is a complete prompt for a research task:
submit_result, no list of the
output fields, no explanation of nulls beyond the policy. All three are
generated from output.
Field descriptions are part of the prompt
Every output field is required and nullable, so the model has to say something about every one of them — including “I could not find it”. The field’sdescription is the only instruction it gets about what belongs there, because
that description becomes the argument’s description in the generated tool
schema. It is literally the prompt for that value.
Which means a vague description does not produce a vague value. It produces a
different value on every run.
The pattern: name the vocabulary or the length, name where to look, and name the
null case. Inputs and output
has more pairs.
Descriptions are not templated.
{{vars.our_product}} in a field
description reaches the model as those literal braces — only the prompt is
substituted. Anything a description needs to know about this run’s inputs has to
be said in the prompt instead.Writing for the two failure modes
no_output and step_limit are the same event underneath: the run ended
without calling submit_result. They are reported apart because the fix is
different, and doing the other one is wasted work.
Do not rewrite a prompt that reported
step_limit. The prompt was not at
fault, and the fix is a number in the task’s Limits section. Rewriting it is the
one piece of work these two error types exist to stop you doing.
attempts tells you how much the platform already tried on your behalf. A run
that ends with no result is re-prompted rather than failed, up to twice, so
attempts is 1, 2 or 3 — and each re-prompt starts the step budget over.
Read it beside the status:
attempts: 1on a completed run is the healthy shape. It worked first go.attempts: 2or3on a completed run means one or two earlier attempts ended with no result and were thrown away. It worked, at two or three times the tokens, and it will start failing as soon as the work gets slightly harder. Fix it now rather than when it breaks.- A
no_outputfailure means every attempt ended in prose. The re-prompts already told the model to produce the result and it still did not, so the problem is upstream of that: look for a sentence in your prompt pulling it towards an essay — “write a summary”, “produce a report”, “explain”. - A
step_limitfailure withattempts: 3is three separate attempts that each burned the full step budget, so a task withmax_steps: 25did up to 75 rounds of work before anything gave up. The clock stopped it, notmax_steps.
error.type, and what each one sends you to change, is in
errors and limits.
Prompting for tools and MCP servers
The model can only call what is attached, and it decides what to call from the tool’s own name and description — the same as an agent. What a task’s prompt adds is order, because a task’s work usually has one.- Name tools by the name the model sees. For a tool that is its
name. For an MCP tool it is the namespacedexposed_name— an integration with atools_namespaceofcrmturns the server’ssearchintocrm_search, and a prompt saying “use search” names nothing.GET /v1/integrations/{integration_id}/mcp-toolslists both names for every tool a server offers. See MCP servers. - Say the order, and say when to stop. “Call
crm_searchfirst with the domain. Only if it returns no rows, fall back toweb_lookup.” A model given three tools and no order will often call all three. - Say what an empty result means. This is the single highest-value sentence
in most task prompts. “If
crm_searchreturns an empty list, the company is not a customer — say so and move on. Do not search again with a different query.” Without it, an empty result reads to the model as a failed attempt, and it retries until the steps run out. - Say what not to call. A task attached to a write-capable MCP server should
be told which of its tools are off limits, in the prompt, as well as narrowed
through
allowed_toolson the integration.
Iterating
Run it, read the trace, change one thing. The trace is every tool call and everything the model wrote, in order, and it answers the question a prompt edit should be based on. Four things it tells you:
That last one is worth reading closely: when the arguments do not match the
schema the model is told what is wrong and may call the tool again, so a run can
finish successfully having wasted two rounds on a description nobody wrote
properly.
Change one thing between runs. A task run is cheap and reproducible in a way
a call is not — the same
vars produce a comparable run every time — so there
is no reason to bundle three edits and guess which one worked.
Complete examples
A research task
A research task
max_steps is raised above the default 25 because a research task genuinely
searches, and timeout_seconds is raised with it — the step budget is the
runaway guard and the clock is the real bound.A classification task
A classification task
max_steps: 3 is deliberate. The task calls no tools, so a healthy run uses one
step — the submit_result call itself — and a run that somehow needs thirty
rounds has gone wrong in a way that should fail fast rather than burn tokens.Notice needs_human says “Send null never; decide”. Every field is nullable in
the generated tool and there is no way to turn that off, so a field that must
always have a value says so in its description.An extraction task
An extraction task
total_amount is a number and payment_terms_days an integer, so
neither can come back as "₹4,20,000" or "net 30".Next
Errors and limits
Every
error.type, and the two budgets that bound a run.Inputs and output
The generated
submit_result tool, and required-and-nullable.Running and runs
Read a run, its trace,
attempts and steps_used.Tools and MCP servers
Attach the things the prompt tells the model to call.