Short answer
Typed errors turn failure into explicit control flow
The tool should return a stable machine-readable code, safe structured details, and a clear statement that no mutation occurred when that is the contract.
An agent can map a version conflict to reread, a schema error to payload repair, a rate limit to bounded backoff, and an authorization failure to stop. If all four arrive as an undifferentiated message, the model must infer control flow from prose and may choose an unsafe branch.
The code does not need to expose internal stack traces or database details. It should communicate the minimum semantic fact required for safe recovery.
Control matrix
Every expected error should have a bounded recovery policy
| Error meaning | Safe next step | Unsafe shortcut |
|---|---|---|
| Invalid input | Repair against the published schema | Keep resending the same payload |
| Version conflict | Reread state and decide again | Change only the version number |
| Rate limited | Wait according to the returned policy | Burst parallel retries |
| Unauthorized | Stop and surface the boundary | Probe identifiers for access |
| Terminal aggregate | Stop mutation attempts | Retry until a call slips through |
Evaluation
Preserve the original error and the recovery sequence
A final success should not erase the initial failure because the repair path is part of the agent's observable behavior.
Record the attempted tool and payload, stable error code, any retry guidance, subsequent reads, repaired request, and final authoritative effect. That sequence distinguishes first-pass correctness from successful recovery.
It also exposes retry loops. Ten identical failures followed by abandonment should not be summarized as one harmless error simply because the interface collapsed duplicate messages.
Boundary
Typed errors improve recoverability but do not choose for the agent
The contract can identify the failure class and available next step; the agent still has to use current context, respect budgets, and know when to stop.
- Keep error codes stable across equivalent failures.
- Validate any structured error details at the client boundary.
- Do not mark an unexpected internal defect as a routine retryable condition.
- Evaluate whether the agent selected the correct recovery branch, not merely whether an error object existed.