[BUG] Tool-result references are not project/session isolated (cross-project content leakage)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
In a session rooted in Project A, a Bash tool call (a Python CLI that only prints JSON) rendered, as its result, an unrelated ~86 KB block of Xcode project.pbxproj debug output belonging to a DIFFERENT project (Project B). The same foreign block appeared in two positions of one combined command's output, byte-for-byte identical.
This is cross-project data leakage. The leaked content was also persisted into Project A's own session transcript (because it was rendered as A's output).
Root cause (hypothesis): Claude Code stores large tool results on disk under a three-level path <project>/<session-id>/tool-results/<id>.txt, but the reference/lookup layer addresses them by a single, globally-flat 9-character id with NO project or session component. The isolation boundary exists in storage but is bypassed by addressing. Under --resume, a persisted id resolves via a global lookup and can land on another project's file. Storage isolation ≠ reference isolation.
What Should Happen?
A tool result rendered in Project A's session must resolve ONLY to that session's own tool-result files. Content from another project or session must never surface.
Suggested fix:
Address tool results by a composite key (project, session, id) (or the full three-segment path) through every lookup.
Or scope the id namespace to the session (encode session into the id).
Add a resolution-time guard: reject a tool-result file whose on-disk (project, session) does not match the resolving session.
Error Messages/Logs
No error was raised — the failure is silent (wrong content returned as success). Forensic data:
Re-running the identical command with stdout/stderr redirected to files: clean correct JSON (676 bytes), empty stderr. sys.modules has no module from the other project; ps shows no related process.
Source: <home>/.claude/projects/<Project B>/<session-B>/tool-results/bs4pgt1ey.txt (86 KB)
Not a collision: 23 files, 23 unique ids; bs4pgt1ey exists in one place only.
Flat id namespace: b1plcujfu, b2vmqiu13, b6o8ofgjy, b6rlypd6m, bdshnv4bi …
Steps to Reproduce
Not deterministically reproducible (intermittent, under --resume). Trigger conditions + forensic verification:
Trigger conditions:
Use Claude Code across multiple projects so several tool-results/<id>.txt accumulate.
Resume a session (--resume <session> --replay-user-messages).
Run a command whose output is large enough to spill to a tool-results file.
Intermittently, the result shows another project's tool-result content.
Forensic verification (deterministic):
Redirect the command's stdout/stderr to files => current process output is clean.
grep the foreign text across ~/.claude/projects/ => found in another project's tool-results/<id>.txt.
List all tool-results/*.txt ids => globally unique, no project/session component.
Environment: Claude Code 2.1.161 (desktop, macOS); model claude-opus-4-8; --resume <session-A> --replay-user-messages.
Note: inverse of #65456 (that asks for intentional cross-project handoff; this is unintended leakage).
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.161
Platform
Other
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Platform: Claude Code desktop app (macOS), not a direct API integration. The Platform field above does not have a "Claude Code" option so "Other" was selected.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗