[BUG] VSCode: hiding a session hides it in every project that shares its sessionId (global hiddenSessionIds, no project scope)

Resolved 💬 1 comment Opened May 11, 2026 by aaron-ang Closed Jun 9, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

The VSCode extension's hidden-session filter (hiddenSessionIds in globalState) is keyed by sessionId only, with no project scoping. If the same <sessionId>.jsonl exists in two project transcript directories under ~/.claude/projects/ — which happens when a user manually copies/moves a transcript across ~/.claude/projects/<encoded-dir>/ folders — hiding the session in project A also makes it disappear from project B. The transcripts on disk are unchanged; only the picker filters them out everywhere.

Note: claude --resume <id> from a different cwd does not trigger this — the CLI rejects cross-project resume with No conversation found with session ID. The duplicate must be created out-of-band (manual cp/mv of the jsonl).

What Should Happen?

Hiding a session in project A should only suppress it in project A's resume picker. The same sessionId appearing under a different project directory should remain visible there.

Error Messages/Logs

No error output. Bug manifests as silent omission from the resume picker.

Steps to Reproduce

Verified on a clean dummy setup:

mkdir -p /tmp/proj_a /tmp/proj_b
cd /tmp/proj_a && git init -q
cd /tmp/proj_b && git init -q

# 1) create a session in proj_a
cd /tmp/proj_a
echo "hi" | claude -p "say one word" --output-format=json
# -> session_id: <SID> ; transcript at ~/.claude/projects/-tmp-proj-a/<SID>.jsonl

# 2) manually copy the transcript into proj_b's folder
SID=<the id from step 1>
cp ~/.claude/projects/-tmp-proj-a/$SID.jsonl ~/.claude/projects/-tmp-proj-b/$SID.jsonl

# 3) optional: confirm resume works in proj_b after the copy
cd /tmp/proj_b
claude -p --resume "$SID" "say one word"
# -> succeeds (it would have failed with "No conversation found" before the copy)

Then in VSCode:

  1. Open /tmp/proj_a, find session <SID> in the resume picker, click Delete.
  2. Open /tmp/proj_b → session <SID> is also gone from the picker, despite its jsonl being untouched in ~/.claude/projects/-tmp-proj-b/.

Original real-world trigger in my case: I manually moved a transcript jsonl from one project's ~/.claude/projects/<encoded-dir>/ to another so the same conversation would appear in the second project's picker.

Verification on local macOS
sqlite3 ~/Library/Application\ Support/Code/User/globalStorage/state.vscdb \
  "SELECT value FROM ItemTable WHERE key='Anthropic.claude-code';" \
| python3 -c "import sys,json; d=json.loads(sys.stdin.read()); print('hidden:', 'X' in d.get('hiddenSessionIds',[]))"
# -> hidden: True
Root cause in extension.js
async listSessions() {
    ...
    let N = new Set(this.settings.getHiddenSessionIds());
    return { sessions: N.size > 0 ? V.filter(B => !N.has(B.id)) : V };
}
getHiddenSessionIds() { return this.context.globalState.get("hiddenSessionIds") ?? []; }
async hideSession(z) { /* pushes plain sessionId string into the array */ }

hiddenSessionIds stores plain UUIDs in globalState and the filter is applied globally — no association with the project the user hid the session in.

Workaround

Rewrite the duplicated jsonl with a fresh UUID in the project where it's incorrectly hidden:

OLD=<sessionId>
NEW=$(uuidgen | tr 'A-Z' 'a-z')
DIR=~/.claude/projects/<encoded-project-dir>
sed "s/$OLD/$NEW/g" "$DIR/$OLD.jsonl" > "$DIR/$NEW.jsonl"
chmod 600 "$DIR/$NEW.jsonl"
rm "$DIR/$OLD.jsonl"

Reload window. Only the sessionId field is rewritten; per-message uuid / parentUuid / leafUuid stay intact and remain valid.

Proposed fix

Store hide entries as {projectPath, sessionId} (or scope by encoded project dir name). Apply filter in listSessions() only when projectPath matches the current workspace. Migrate existing entries on next launch by attributing them to whichever project dir's jsonl currently exists.

Claude Model

Not sure / Multiple models

Is this a regression?

I don't know

Last Working Version

n/a

Claude Code Version

2.1.138 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

VS Code integrated terminal

Additional Information

The Claude Code VSCode extension is a "ui" type extension, so its globalState lives on the user's local machine (here: macOS), while the session transcripts live on the remote dev host (here: Ubuntu Linux over Remote SSH). This split makes the symptom confusing — the transcripts on the remote are intact and the extension reads them fine; the filter is solely on the local side.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗