Update
The agent repairs rejected columns, scope refusals and bad tool names instead of giving up
TL;DR
Three failures that looked unrelated turned out to share a shape: the agent had enough information to fix the problem and no mechanism to act on it. Each is now repaired where it occurs rather than surfacing as a dead end.
What shipped
- Scope refusals retry themselves once. After re-authorizing, a request could still fail with insufficient permissions for a few minutes — a cached token on a different instance. The retry is safe for writes too: a permissions refusal means the call never executed.
- Malformed tool names are repaired at the dispatch seam. A tool named with a dotted prefix could be blanked by the name normalizer, so the call dispatched to nothing — and the agent's own attempt to correct itself was erased by the same step. Fixed once at the seam, so it covers every lane.
- A rejected column is repaired rather than abandoned. When a reporting API refuses a metric, the error now carries a hint naming the valid alternative, and the plan is rewritten deterministically instead of asking the model to guess.
- Comparing amounts in different currencies converts them instead of placing them side by side — and covers every money metric in the comparison, not just the headline one.
- First-run playbooks are seeded on the first task, not on the first visit to the skills page. Five organizations with connected accounts had none, because they had never opened that page.
Why these are one release
Each was found the same way — by reading traces of real runs rather than test fixtures — and each was a case where the failure message already contained the fix. An agent that stops at an error it could have resolved reads as much less capable than one that recovers, even when the underlying coverage is identical.
Frequently asked questions
- Is retrying a write after a permissions error safe?
- Yes. A scope refusal means the provider rejected the request before executing it, so nothing was written. The retry happens once, and only for that specific class of refusal.
- Why did I get a permissions error right after re-authorizing?
- A token cached on another server instance could outlive the re-authorization by a few minutes. The stored and freshly fetched tokens both had the right scopes; a warm instance was still holding the old one. That case now retries itself.
- What happens when a reporting API rejects a metric?
- The error is parsed for the valid alternative and the plan is rewritten deterministically. Previously the run either stopped or the model guessed a replacement.