Tool results delayed/batched after host sleep, with no in-flight signal — agent busy-polls with no-op calls
Environment
- Claude Code: 2.1.158
- Surface: VS Code extension
- OS: Windows 11 (win32)
- Model: Claude Opus 4.8 (1M context)
What happened
During a long autonomous task (a production deploy followed by a ~30-minute "soak"/monitoring window), tool-call results repeatedly stopped returning for long stretches and then arrived all at once in large batches. The batches lined up with background-task completion notifications and, in the worst case, with the host machine waking from sleep/suspend.
A background poller's own timestamps made the host-sleep obvious — consecutive iterations jumped from 10:56:52Z to 14:20:29Z (~3.5h gap) even though the loop slept only 60s between polls. So real wall-clock advanced while the machine was suspended, and no tool results could be delivered during that window.
Impact
From inside the agent loop there was no way to distinguish between:
- a foreground tool call still running,
- results merely queued / batched, and
- the host being suspended.
With no in-flight or heartbeat signal, the agent concluded the "channel" was wedged and emitted hundreds of no-op true Bash calls trying to force a flush — burning tokens and turns for zero benefit.
Notably, run_in_background tasks did reliably re-invoke the agent on completion, which turned out to be the dependable wake primitive — but that wasn't discoverable in the moment, so the model fell back to busy-polling instead.
Repro (approximate)
- Start a long task that issues tool calls over many minutes.
- Let the host sleep/suspend (or otherwise stall result delivery) for an extended period.
- Observe: tool results stop returning, then flush in a large batch on resume; nothing indicates which of the three states above you are in.
Suggestions
- In-flight indicator / heartbeat for pending or long-running tool calls, so silence is distinguishable from a hang.
- Detect and surface host sleep/suspend (e.g., a "session resumed after N minutes suspended" marker) so the agent doesn't misread the gap as a wedged channel.
- Backpressure / a hint that discourages degenerate no-op polling and points the model at background-task completion notifications as the proper wait mechanism.
---
Filed at a user's request after a deploy task that took far longer than it should have, largely due to the above behavior.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗