Skip to content

Fix session visibility marks leaking across sessions#3132

Merged
jlowin merged 1 commit intomainfrom
fix/session-visibility-leakage
Feb 10, 2026
Merged

Fix session visibility marks leaking across sessions#3132
jlowin merged 1 commit intomainfrom
fix/session-visibility-leakage

Conversation

@jlowin
Copy link
Copy Markdown
Member

@jlowin jlowin commented Feb 10, 2026

Visibility._mark_component() was mutating the shared component objects cached in providers. Since all sessions receive the same Tool/Resource/Prompt instances from _list_tools(), a session-level disable_components() call would stamp visibility: False directly onto the shared object's .meta dict. After reset_visibility() cleared the session rules, apply_session_transforms() would find no rules, return early — and the shared objects still carried the stale marks. This also caused marks to leak to concurrent sessions.

The fix is a one-line semantic change: _mark_component now returns component.model_copy(update={"meta": new_meta}) instead of mutating in-place. This matches the existing pattern used by Namespace transform. Each list_tools() call now works with fresh copies, so session marks never persist on the provider's cached objects.

# This now works correctly across repeated cycles:
await ctx.disable_components(tags={"system"})  # tools hidden
await ctx.reset_visibility()                    # tools visible again
await ctx.disable_components(tags={"system"})  # tools hidden again (was broken)

Fixes #3034

Visibility._mark_component() mutated shared component objects cached in
providers, causing session-level disable/enable marks to persist after
reset_visibility() and leak to other sessions. Now returns model_copy()
instead of mutating in-place.

Fixes #3034
@jlowin jlowin added bug Something isn't working. Reports of errors, unexpected behavior, or broken functionality. server Related to FastMCP server implementation or server-side functionality. v3 Targeted for FastMCP 3 labels Feb 10, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 10, 2026

Walkthrough

The _mark_component function in src/fastmcp/server/transforms/visibility.py was refactored to avoid in-place mutation of component metadata. The function now constructs a new metadata dictionary and returns a component copy with updated metadata via component.model_copy(update={"meta": new_meta}), rather than directly mutating component.meta. The docstring was updated to reflect that the method returns a copy with updated metadata. Logic flow remains unchanged when no match occurs.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main fix: preventing visibility marks from leaking across sessions by avoiding in-place mutations of shared component objects.
Description check ✅ Passed The description comprehensively explains the root cause, the fix, and provides a clear example demonstrating the corrected behavior. It includes the issue reference (#3034).
Linked Issues check ✅ Passed The PR directly addresses the core requirements of issue #3034: preventing session visibility marks from persisting on shared provider-cached objects and ensuring marks don't leak across sessions.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the visibility mutation bug described in issue #3034. The modification to _mark_component and docstring update are focused and necessary for the fix.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/session-visibility-leakage

No actionable comments were generated in the recent review. 🎉

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jlowin jlowin merged commit 40e80d6 into main Feb 10, 2026
14 checks passed
@jlowin jlowin deleted the fix/session-visibility-leakage branch February 10, 2026 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working. Reports of errors, unexpected behavior, or broken functionality. server Related to FastMCP server implementation or server-side functionality. v3 Targeted for FastMCP 3

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Per-session visibility/tools disabling can't be reversed and affects other sessions

1 participant