Tool errors must be typed for the agent, not logged for the operator

Agentic AI SeedlingPlanted Sep 2026

I think tool errors must be typed for the agent, not merely logged for the operator. A stack trace, opaque code, or success-shaped empty result may help a developer after the incident, but it gives the runtime no reliable next move. For an agent, an error is part of the control protocol. It must say whether to repair the request, retry later, choose another tool, compensate for an effect, or stop and escalate.

The useful taxonomy is small. Validation means the proposed call is malformed or outside the schema and should be corrected before execution. Authorization means the action is not permitted and retrying unchanged is wrong. Not-found means the referenced entity or capability is absent and the plan may need revision. Transient means the same intent may succeed after bounded backoff. System means the dependency or tool is unhealthy and a circuit breaker or fallback should engage. Semantic failure means execution succeeded but the result did not satisfy the task. These classes drive different branches.

This is where tool design becomes API design under uncertainty. The error envelope should carry a stable type, retryability, human-readable message, invalid field or failed precondition, safe correction hint, effect status, and a correlation identifier for the operator record. The agent needs the minimal structured facts required to recover. The operator can follow the identifier to detailed logs. Dumping internals into model context adds tokens, leaks implementation detail, and still avoids the decision the runtime needs.

Validation should happen before effects. Strict schemas can eliminate structural failures, but they cannot establish that an identifier belongs to this tenant, a value is sensible for the domain, or the permission remains valid now. Those checks belong at the execution boundary, and their failures should return the same typed contract as downstream failures. Structured outputs are integration contracts; an error is not an exception to that principle but one of its most important variants.

Retry policy follows the type, not the model’s optimism. Transient failures get capped exponential backoff and jitter. Validation failures get one corrected call rather than the same payload repeated. Authorization failures stop. Persistent system failures trip a circuit breaker. Calls with external effects also report whether the effect was definitely absent, definitely committed, or unknown. Without that distinction, an agent can turn uncertainty into duplicate payments, messages, or writes.

Typed errors also make product behavior visible. Repeated validation failures expose a bad schema or description. Not-found clusters expose stale plans or discovery. Authorization failures expose misplaced capability. Unknown-effect failures belong in the exception queue because a person may need to reconcile external state before execution resumes. A generic “tool failed” metric collapses all of those operating problems into noise.

There is one precise concession: during local development, a raw stack trace can be the fastest diagnostic for the engineer who owns both caller and tool. It should remain in protected logs, not become the production response contract. The boundary appears as soon as a probabilistic caller, another team, a tenant, or sensitive data sits on the other side.

I would review every tool by forcing each failure class and checking the next transition. Does the agent repair only what is repairable, retry only what is retryable, preserve uncertain effects, and escalate with enough context? A useful error does not merely describe what broke. It constrains what the agent may safely do next.