Why does my agent ignore a soft decline?

A soft decline, a warning, a partial success: your tools return them, your agent reads past them. It treats a 200 with an error in the body as a green light and chains the next wrong step.

B

Balagei G Nagarajan

5 MIN READ


Agents routinely read a failed tool call as a success.A 2025 study of how LLM agents fail found they silently misread tool errors, partial results, and warnings as completion and march on, rather than detecting and recovering (Where LLM Agents Fail and How They Learn From Failures, arXiv:2509.25370, 2025). If any of your tools can return a soft decline or a 200 with an error inside, your agent is one unread field away from shipping the next wrong step.

A traffic signal glowing green while, faintly inside the green lens, a small amber warning symbol goes unnoticed by the figure driving through
Agents don't, unless the output makes the nuance impossible to miss.
— from “Why does my agent ignore a soft decline?”

Key facts.

What counts as a tool-output nuance?

it's any signal in the response that isn't a clean success but isn't a hard failure either. A payment that came back as a soft decline, retryable, not refused. A batch job that processed 8 of 10 records and warned about 2. A 200 OK whose body contains a status of error. A rate-limit warning in a header. A search that returned an empty list rather than a match. Each of these means don't proceed as if this fully worked, and each is easy for a model to read past, because the surrounding text looks like a normal result. Engineers parse these by habit. Agents don't, unless the output makes the nuance impossible to miss.

Why do agents read past these signals?

Because the agent treats the tool result as language, not as a typed contract. In a typical loop the observation is concatenated into the conversation and the model continues. It pattern-matches: the response is well-formed, it has fields, it resembles the successes it saw in training, so it moves on. there's no step that says extract the status, check for warnings, confirm completeness, and stop if any of those say no. Studies of real agent runs show how unreliable this is: agents misread tool outputs and move on because nothing forces them to extract status, warnings, and completeness before the next step (Where LLM Agents Fail).

How do you make the nuance impossible to ignore?

Shape the output so the agent can't proceed without reading the important part. Return a structured envelope with explicit fields: a status enum, a warnings array, a completeness or count field, and a typed error object that's never hidden inside a success body. Use real HTTP semantics so a decline isn't a 200. Then add a validation step in the runtime that inspects those fields and routes anything that isn't a clean success to a retry, an escalation, or a halt, before the next tool call runs. Research on agent failure recovery shows agents can recover from tool failures once they're made to detect them, but the cheapest win is making detection structural instead of hoping the model notices.

A funnel where five distinct inputs, 200-with-error, warning, partial result, soft decline, empty set, all collapse into a single output box labeled SUCCESS, with a verify gate shown missing in the funnel's neck

What the agent assumes versus what happened

Tool returnsAgent assumesWhat happenedGuardrail
200 with error bodySuccessThe operation failedTyped error envelope, never error-in-200
Soft declineCapturedRetryable non-captureStatus enum + retry path
Partial batch (8/10)All doneTwo records droppedCompleteness/count field + check
Warning headerClean resultDegraded or throttledWarnings array surfaced to runtime
Empty result setNot found, doneThe query was wrongDistinguish empty from error, validate

The pattern is that an agent reads tool output as prose and rewards itself for any well-formed response, so a soft decline wrapped in a 200 is invisible until it has poisoned the downstream steps. Give every tool a structured success-or-failure envelope and verify it before the next action, and the nuance becomes a fact the agent has to act on. That verification layer, checking the outcome instead of trusting the wrapper, is what VibeModel builds as the Pattern Intelligence Layer.

Frequently asked questions

Why is an error inside a 200 so dangerous?
Because the status line says success and the model trusts it. The failure is in the body, which the agent reads as ordinary data, so it proceeds. Use real HTTP semantics and a typed error object so a failure is never dressed as a 200.

Can I fix this with a better prompt?
Partly, but prompts are a soft guardrail. The reliable fix is structural: a status enum, warnings array, and completeness field the runtime checks, so success is verified rather than assumed.

what's the cheapest first step?
Stop returning errors inside success bodies. A single typed envelope with an explicit status field removes the most common way agents mistake failure for success.


Share this post

Join the discussion

Have a take, a war story, or a question? Sign in with GitHub to comment and react. Comments are powered by GitHub Discussions, ad-free and yours to moderate.

Continue Reading

Find where your agent breaks, before you build it

Faultmap maps where your agent will fail from the goal and your data, then hands you the first test suite it has to pass.