Skip to content

fix(runtime): guard onToolsChanged like onBackgroundEvent (#3594)#3609

Draft
aheritier wants to merge 1 commit into
mainfrom
fix/3594-guard-ontoolschanged
Draft

fix(runtime): guard onToolsChanged like onBackgroundEvent (#3594)#3609
aheritier wants to merge 1 commit into
mainfrom
fix/3594-guard-ontoolschanged

Conversation

@aheritier

Copy link
Copy Markdown
Contributor

Summary

Fixes #3594onToolsChanged was written and read from MCP
change-notification goroutines with no synchronization, while its sibling
onBackgroundEvent is already mutex-guarded (backgroundEventMu) with a
comment explaining exactly this hazard.

This is finding A5 from the internal codebase audit.

What changed

  • onToolsChanged is now guarded by a new toolsChangedMu sync.RWMutex,
    faithfully mirroring the onBackgroundEvent/backgroundEventMu precedent:
    the setter writes under the write lock; emitToolsChanged copies the handler
    under the read lock and then releases it before reading tools,
    constructing the event, and invoking the handler (never holding the mutex
    across the callback).

Testing

  • pkg/runtime/ontoolschanged_race_test.go — concurrent register + emit.
    Verified to fail (data race at the setter write + the two reads) against the
    pre-fix unguarded code and pass now.
  • task dev + go test -race -count=2 ./pkg/runtime/...: green (validated in
    isolation).

Opened as a draft pending final maintainer review.

@aheritier aheritier added kind/fix PR fixes a bug (maps to fix:). Use on PRs only. area/runtime Runtime engine, agent loop execution, tool dispatch, loop detection area/mcp MCP protocol, MCP tool servers, integration labels Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/mcp MCP protocol, MCP tool servers, integration area/runtime Runtime engine, agent loop execution, tool dispatch, loop detection 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.

fix(runtime): guard onToolsChanged like onBackgroundEvent

1 participant