Skip to content

fix: serialize concurrent RunSession calls to prevent tool_use/tool_result mismatch#2375

Merged
dgageot merged 1 commit intodocker:mainfrom
dgageot:board/session-concurrency-issue-with-tool-call-492e1cda
Apr 10, 2026
Merged

fix: serialize concurrent RunSession calls to prevent tool_use/tool_result mismatch#2375
dgageot merged 1 commit intodocker:mainfrom
dgageot:board/session-concurrency-issue-with-tool-call-492e1cda

Conversation

@dgageot
Copy link
Copy Markdown
Member

@dgageot dgageot commented Apr 10, 2026

When two HTTP requests target the same session concurrently, the second
can inject user messages while the first is mid-tool-call, producing a
tool_use without a matching tool_result that causes Anthropic API errors.

Add a per-session streaming mutex to activeRuntimes. RunSession uses
TryLock to fail fast with ErrSessionBusy (HTTP 409) when the session is
already streaming. Message addition is deferred until after the lock is
acquired, so a rejected request never mutates the session.

TryLock is called on the calling goroutine inside RunSession; Unlock is
deferred in the background goroutine after RunStream completes. The lock
is held continuously from before message addition through the entire
stream including all tool-call processing.

…esult mismatch

When two HTTP requests target the same session concurrently, the second
can inject user messages while the first is mid-tool-call, producing a
tool_use without a matching tool_result that causes Anthropic API errors.

Add a per-session streaming mutex to activeRuntimes. RunSession uses
TryLock to fail fast with ErrSessionBusy (HTTP 409) when the session is
already streaming. Message addition is deferred until after the lock is
acquired, so a rejected request never mutates the session.

TryLock is called on the calling goroutine inside RunSession; Unlock is
deferred in the background goroutine after RunStream completes. The lock
is held continuously from before message addition through the entire
stream including all tool-call processing.

Assisted-By: docker-agent
@dgageot dgageot requested a review from a team as a code owner April 10, 2026 14:03
@dgageot dgageot merged commit 9f3d6d2 into docker:main Apr 10, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants