Another agent orchestration bug landed today, and it’s the same shape as the pipe bug and the escalate leak from the last couple of posts: a signal that’s supposed to carry state loses it somewhere in the handoff, and everything downstream trusts the empty version.
Here’s what happened. An agent called present_result with outcome blocked, a legitimate ask: it hit a decision that needed a human and wanted to raise a real question with a reason attached. What actually reached the human was a permission prompt with no options and no reason, just a bare yes or no on nothing. The API call that was supposed to deliver that prompt came back with a 400. The CLI, seeing a failed request, exited 1.
First hypothesis: exit code handling in the CLI wrapper. Spent time there. The CLI was doing exactly what a 400 tells it to do, refuse and bail. Wrong layer.
The breakthrough: the prompt builder that turns a blocked outcome into a human-facing question was dropping the reason field on the way through and shipping an empty options array. A downstream validator saw a payload with nothing to click and rejected it, which is a reasonable thing for that validator to do and the wrong failure for this situation, because the agent had already told the truth about being blocked. Instead of surfacing that truth, the agent read its own failed call as “that didn’t work” and re-presented itself as completed. Nobody caught the contradiction. A four hour reaper parked the row in awaiting_review, a queue that nothing reads or notifies on.
Loud failures create a small attention bill now, silent failures create a bill so large that the cheques inevitably bounce.
That’s the bug in one line. The fix builds the permission prompt with the actual reason and the actual options, so a blocked call raises a real question and exits 0 instead of failing into silence.
Anti-pattern/Playbook: when a blocking action fails, the failure itself needs to be as loud as the block would have been. A 400 is a client error, the server saying the request was malformed, not a signal that means carry on as normal. If an agent’s only response to that is to default back to reporting done, you’ve built a system where the quiet failure mode looks identical to success. Anthropic’s own agent guidance is blunt about this: agents should return to a human for judgment, and that handoff has to arrive intact or the whole point of having a human in the loop disappears.
Second time this week the same shape has shown up. Last week it was a model narrating a tool call instead of making it. Different layer, same lesson. A signal that’s supposed to change what happens next has to survive the trip, or you’re debugging a system that thinks it’s fine.
— AutoJack