Repository navigation
Concurrent background-job elicitations are silently dropped — nothing displayed to the user #3584
Copy link
Copy link
Labels
area/apiFor features/issues/fixes related to the usage of the cagent APIFor features/issues/fixes related to the usage of the cagent APIarea/runtimeRuntime engine, agent loop execution, tool dispatch, loop detectionRuntime engine, agent loop execution, tool dispatch, loop detectionarea/tuiFor features/issues/fixes related to the TUIFor features/issues/fixes related to the TUIkind/fixPR fixes a bug (maps to fix:). Use on PRs only.PR fixes a bug (maps to fix:). Use on PRs only.
Description
Activity
- addedkind/fixPR fixes a bug (maps to fix:). Use on PRs only.PR fixes a bug (maps to fix:). Use on PRs only.area/runtimeRuntime engine, agent loop execution, tool dispatch, loop detectionRuntime engine, agent loop execution, tool dispatch, loop detection
on Jul 10, 2026 - addedarea/tuiFor features/issues/fixes related to the TUIFor features/issues/fixes related to the TUIarea/apiFor features/issues/fixes related to the usage of the cagent APIFor features/issues/fixes related to the usage of the cagent API
on Jul 10, 2026 - added 7 commits that reference this issue
on Jul 13, 2026 - added a commit that references this issue
on Jul 13, 2026 13 remaining items
- added 9 commits that reference this issue
on Jul 15, 2026 - added a commit that references this issue
on Jul 16, 2026 - added a commit that references this issue
on Jul 16, 2026
Metadata
Metadata
Labels
area/apiFor features/issues/fixes related to the usage of the cagent APIFor features/issues/fixes related to the usage of the cagent APIarea/runtimeRuntime engine, agent loop execution, tool dispatch, loop detectionRuntime engine, agent loop execution, tool dispatch, loop detectionarea/tuiFor features/issues/fixes related to the TUIFor features/issues/fixes related to the TUIkind/fixPR fixes a bug (maps to fix:). Use on PRs only.PR fixes a bug (maps to fix:). Use on PRs only.
Summary
When user input (an elicitation request) is triggered from multiple concurrent background jobs, nothing is displayed to the user at all — the request is silently dropped and the requesting handler blocks forever. This is a functional failure experienced frequently in practice, not just a theoretical race.
Root cause
The elicitation path assumes a single, synchronous, LIFO-nested request at a time, which breaks under concurrency (e.g.
run_background_agentjobs runningRunStreamon detached concurrent goroutines):elicitationBridgeis a single global channel slot with a LIFO-nesting assumption (pkg/runtime/elicitation.go:59,pkg/runtime/loop.go:307/217). Concurrent background jobs cause the swaps/restores to interleave arbitrarily.runCollectingsilently discardsElicitationRequestEvents — it only handles content/tokens/errors (pkg/runtime/agent_delegation.go:366-383). So a background job's elicitation event lands in a collector that drops it while the handler parks forever.errNoElicitationChannel/ recover path) → silent failure; foreground elicitations can also bleed into a background collector.PendingEventis a single overwritable slot (pkg/tui/.../supervisor.go:28/202).ResumeElicitation'sdefault:branch returns "no elicitation request in progress" if the response lands in the gap before the handler parks.ElicitationIDexists on the request event but is unused for routing.Proposed fix
ElicitationID(register-before-emit, eliminating the TOCTOUdefault:branch).OnElicitationRequestUI sink mirroring the existingOnBackgroundEventsink so background-job elicitations are surfaced to the foreground UI.elicitation_idfield onapi.ResumeElicitationRequest(it does not carry one today).Acceptance criteria
-race).