[BUG] Code/SSH: all session history blank when ~/.claude/projects is a symlink (transcript locator runs `find` without -L)

Resolved 💬 1 comment Opened Jun 25, 2026 by mdavies Closed Jul 8, 2026

Preflight Checklist

  • [x] I have searched existing issues and this specific cause does not appear to be documented
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

In the Desktop Code tab driving a remote CLI over SSH (e.g. WSL), every previously-used session opens to a blank pane ("No messages yet"), even though:

  • the session is listed in the sidebar with correct title/folder,
  • claude --resume <id> loads the full transcript fine, and
  • the .jsonl transcript is intact on disk.

This happens specifically when ~/.claude/projects is a symlink — common when that directory is managed via dotfiles or a synced git repo. It affects every session, regardless of project.

This is distinct from #38691 / #56172 (missing cliSessionId / transcriptUnavailable): here the Desktop metadata is healthy, and the failure is purely a symlink-unaware find.

Root Cause

The Desktop locates a session's transcript on the remote by running (observed in ssh.log):

sh -c find "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/projects -name '<cliSessionId>.jsonl' -print -quit 2>/dev/null

This omits -L. GNU find in its default -P mode does not descend into a symbolic link supplied as a starting point. So when ~/.claude/projects is a symlink, the command matches nothing and exits 0 with empty output, and the SSH layer logs:

[SSH] Byte-syncing transcript for session local_<uuid> from remote
[SSH] No remote transcript found yet for session local_<uuid>

→ the conversation pane stays empty for every session. (The search is by filename, so the project-slug subdirectory is irrelevant here.)

claude --resume is unaffected because normal open() / path resolution follows symlinks; only find's directory traversal is opted out by the missing -L.

Reproduction

# Make ~/.claude/projects a symlink, as a dotfiles/synced setup would:
mv ~/.claude/projects ~/claude-projects
ln -s ~/claude-projects ~/.claude/projects

# The locator now finds nothing:
find ~/.claude/projects  -name '<some-id>.jsonl' -print -quit    # (empty)

# Either of these fixes it:
find -L ~/.claude/projects -name '<some-id>.jsonl' -print -quit  # found
find ~/.claude/projects/   -name '<some-id>.jsonl' -print -quit  # found (trailing slash)

Then open any prior session in the Desktop Code tab → blank pane.

Suggested Fix

Add -L to the locator (or append a trailing slash to the start path):

find -L "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/projects -name '<id>.jsonl' -print -quit

Both make find descend through the symlinked directory; -L is the more robust choice (it also handles a symlinked project subdirectory or transcript file).

Environment

  • Claude Desktop (Code tab) driving a WSL CLI over SSH
  • Desktop app v1.15200.0.0; remote helper ccd-cli 2.1.187
  • Windows 11 + WSL2 (Ubuntu, systemd)
  • ~/.claude/projects is a symlink to a git-backed directory

Workaround

Make ~/.claude/projects a real directory (so find descends) without moving any data — bind-mount the real location over it:

rm ~/.claude/projects && mkdir ~/.claude/projects
sudo mount --bind /path/to/real/projects ~/.claude/projects
# persist (systemd reads fstab):
#   /path/to/real/projects  /home/<user>/.claude/projects  none  bind  0  0

View original on GitHub ↗

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