Skip to content

fix: prevent concurrent LoadWithConfig calls from sharing working dir - #3842

Merged
dgageot merged 1 commit into
mainfrom
fix/teamloader-workingdir-session-isolation
Jul 27, 2026
Merged

fix: prevent concurrent LoadWithConfig calls from sharing working dir#3842
dgageot merged 1 commit into
mainfrom
fix/teamloader-workingdir-session-isolation

Conversation

@dgageot

@dgageot dgageot commented Jul 27, 2026

Copy link
Copy Markdown
Member

pkg/teamloader.LoadWithConfig previously mutated the caller's *config.RuntimeConfig directly — writing runConfig.WorkingDir to the value supplied by WithWorkingDir, then restoring the original in a defer. The API server holds a single shared sm.runConfig and passes it to LoadWithConfig for every session. Because sessions load concurrently, two simultaneous RunSession calls could observe each other's working directory inside that mutate-and-restore window. Toolsets (shell, filesystem, git, backgroundjobs, mcp, lsp) read runConfig.WorkingDir at creation time, so a session's tools could be rooted in another session's directory — a genuine isolation break, not just a cosmetic race.

When WithWorkingDir supplies a directory that differs from runConfig.WorkingDir, LoadWithConfig now clones the RuntimeConfig and works on the copy. The caller's config is never touched, so there is no window to race on. Callers that do not pass WithWorkingDir (CLI, MCP, A2A, ACP, and others) keep the existing behaviour, including the Models/Providers/ProviderRegistry write-back; pkg/server reads model info from LoadResult rather than from the config, so nothing depends on the write-back on that path.

TestLoadWithConfig_WithWorkingDirIsConcurrencySafe reproduces the bug: 8 concurrent loads share one RuntimeConfig, each with its own WithWorkingDir, and a recording toolset registry captures which directory each toolset was built with. Against the old code all 8 sessions got the same directory; the test passes cleanly with the fix, including under -race -count=3.

WithWorkingDir now clones the RuntimeConfig when the supplied directory
differs from the caller's, so concurrent API-server sessions can't
clobber each other's shell/filesystem/git toolset roots.

Assisted-By: Claude
@dgageot
dgageot requested a review from a team as a code owner July 27, 2026 11:07
@aheritier aheritier added kind/fix PR fixes a bug (maps to fix:). Use on PRs only. area/core Core agent runtime, session management labels Jul 27, 2026
@dgageot
dgageot merged commit 213fcab into main Jul 27, 2026
14 checks passed
@dgageot
dgageot deleted the fix/teamloader-workingdir-session-isolation branch July 27, 2026 11:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Core agent runtime, session management kind/fix PR fixes a bug (maps to fix:). Use on PRs only.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants