You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
AcpSyncClient.prompt wedges on multi-prompt sessions under CPU contention #14
On a CPU-saturated machine (shared CI runners, or locally under taskset -c 0), AcpSyncClient.prompt(...) never returns: it blocks for the entire configured requestTimeout, then fails with a Reactor timeout (FluxTimeout).
Trigger: more than one prompt on the same session. Single-prompt exchanges always pass; the second or third prompt is the one that wedges.
Repro: AcpSyncAgent + AcpSyncClient over InMemoryTransportPair, one session, three sequential prompts, run with CPUs restricted (taskset -c 0). Passes instantly on an idle multi-core box.
Reproduced and fixed. With your exact shape (AcpSyncAgent + AcpSyncClient over InMemoryTransportPair, one session, three prompts, taskset -c 0) the second or third prompt wedged in 4 of 5 runs on main.
Cause: the agent released its single-turn prompt lock in doFinally, i.e. after the response had already reached you. On one CPU your next prompt arrived before that release and was rejected with -32000 There is already an active prompt execution; the rejection's emission then collided with the still-running response emission on the same sink (FAIL_NON_SERIALIZED), which the in-memory transport turned into a fatal error for the agent, and the shipped transports silently dropped. So prompt() waited out the whole requestTimeout.
Fix in e4da7c5, on main for 0.18.0: the lock is released before the response is published (success and error paths), a handler that throws can no longer hold it, and response emission is serialised the way sendMessage already was. Your repro is now MultiPromptSyncSessionTest, and CI runs it pinned to one CPU so the window stays open. Thanks for a report precise enough to reproduce in one go.
Thanks @markpollack I'd love to help on this more - I'm working on some QUIC protocol work, and this is always fun to work with. Let me know if there's room for more help.
Activity
markpollack commentedon Sep 24, 2026
Reproduced and fixed. With your exact shape (
AcpSyncAgent+AcpSyncClientoverInMemoryTransportPair, one session, three prompts,taskset -c 0) the second or third prompt wedged in 4 of 5 runs onmain.Cause: the agent released its single-turn prompt lock in
doFinally, i.e. after the response had already reached you. On one CPU your next prompt arrived before that release and was rejected with-32000 There is already an active prompt execution; the rejection's emission then collided with the still-running response emission on the same sink (FAIL_NON_SERIALIZED), which the in-memory transport turned into a fatal error for the agent, and the shipped transports silently dropped. Soprompt()waited out the wholerequestTimeout.Fix in e4da7c5, on
mainfor 0.18.0: the lock is released before the response is published (success and error paths), a handler that throws can no longer hold it, and response emission is serialised the waysendMessagealready was. Your repro is nowMultiPromptSyncSessionTest, and CI runs it pinned to one CPU so the window stays open. Thanks for a report precise enough to reproduce in one go.krickert commentedon Sep 25, 2026
Thanks @markpollack I'd love to help on this more - I'm working on some QUIC protocol work, and this is always fun to work with. Let me know if there's room for more help.
Break up the stdio transports' read and write loops
Model check the concurrent state with Lincheck, and fix what it found
Keep a cancelled prompt's turn until its response