[BUG] Desktop shows "no messages yet" for SSH/remote sessions on reopen (transcript intact on remote host, context preserved)
Summary
When Claude Code Desktop connects to a remote host over SSH, closing and reopening the app shows "no messages yet" for those remote sessions — the message list renders empty. However, the conversation context is fully intact: asking the model to "summarize this conversation" returns the entire prior discussion. The transcript .jsonl on the remote host is complete and uncorrupted.
So this is a client-side hydration bug specific to remote/SSH sessions: the Desktop UI on the Mac does not load/render the remote host's transcript message list on reopen, even though the remote backend reads it correctly (hence preserved context).
Local (Mac-directory) sessions are unaffected — their history displays normally on reopen.
Environment
- Desktop app (macOS): Claude 1.19367.0 (1a5be1), 2026-07-07
- Remote host: Raspberry Pi 5, Ubuntu 24.04.4 LTS, aarch64, Linux 6.8.0-1060-raspi
- Remote backend (from session env):
CLAUDE_CODE_ENTRYPOINT=claude-desktop,CLAUDE_CODE_EXECPATH=/home/<user>/.claude/remote/ccd-cli/2.1.202,CLAUDE_SSH_DAEMON_CHILD=1
Steps to reproduce
- From Claude Code Desktop (macOS), connect to a Linux host over SSH and hold a normal multi-turn conversation.
- Fully quit the Desktop app on the Mac and reopen it.
- Open the remote (SSH) conversation.
Expected
The full message history renders in the UI (as it does for local Mac-directory sessions).
Actual
- The message list shows "no messages yet" (empty).
- Context is not lost: "summarize this conversation" returns the complete prior discussion.
- The transcript on the remote host is complete and well-formed.
Evidence (data is intact on the remote host)
The remote .jsonl for one such session holds the full history, yet the Desktop UI showed it as empty on reopen:
$ f=~/.claude/projects/-home-<user>-Documents-MAC/f213b833-....jsonl
$ grep -c '"type":"user"' $f -> 128
$ grep -c '"type":"assistant"' $f -> 230
$ wc -l < $f -> 571
# roles are present and ordered from the start of the file (user, attachments, user, ...)
128 user + 230 assistant messages present on the remote host, but the Mac UI rendered "no messages yet" — while the backend clearly still reads the same file (context preserved). This rules out transcript corruption and points to the Desktop client not fetching/rendering the remote transcript on reopen.
Not a duplicate of #24304
#24304 ("Conversation history missing on resume (except last message)") is caused by JSONL corruption (colliding messageId/uuid, broken parent chain), affects local sessions too, and shows the last message. This report is different: the JSONL is uncorrupted, it is specific to remote/SSH sessions, local sessions are fine, and the UI shows zero messages ("no messages yet"), not the last one.
Likely same area as #76114
#76114 reports that Desktop remote (SSH) sessions never create file-history snapshots on the remote host, breaking rewind. Both look like the same underlying gap: the Desktop client fails to sync/hydrate remote-host session state back to the Mac UI — there it's the file-history snapshots, here it's the transcript message list.
Showing cached comments. Read the full discussion on GitHub ↗
4 Comments
Corroborating report — same bug on ccd-cli
2.1.205, x86_64 Ubuntu remote, triggered by a host reboot + app relaunch. Different setup than the OP, which suggests this isn't macOS-specific and still reproduces (or regressed) in 2.1.205.Environment
Linux 6.8.0-134-genericCLAUDE_CODE_ENTRYPOINT=claude-desktop, exec path~/.claude/remote/ccd-cli/2.1.205, active server build under~/.claude/remote/srv/Same symptom
Switching to / reopening a remote SSH session shows "No messages yet" over a fully intact transcript. Verified on the remote host:
.jsonl: 547 user + 1315 assistant messages,wc -l= 2559, 0 malformed lineswc -l= 655, 0 malformed linesContext is preserved (the backend clearly reads the file) — only the UI message list renders empty.
Extra observations that may help localize it
ccd-cli … --resume <sessionId> … --replay-user-messages --include-partial-messages, streams stdout/stderr, and every subprocess exits0.remote-server.loghas no errors.psshows exactly one clean 2.1.205--resumeprocess per open tab (no orphans, no version mixing). This strongly supports the "client-side hydration bug specific to remote/SSH sessions" framing in the OP.sessionId(new UUID containing only the post-reboot turns), while the original full transcript sat untouched under a different UUID. This looks like the same failure as #73526 (cliSessionId missing/nulled → a new message forks a disconnected session).~/.claude.json→projects[<remote-project>].historyis[]after the relaunch — consistent with #63025's "projects field nulled after desktop restart," though here it's specifically thehistoryarray that's empty.Reliable workaround
SSH into the remote host and run
claude --resume <id>from a terminal — the CLI hydrates the full history correctly. (Close the desktop tab for that session first, so two processes don't attach to one session.)Likely the same root cluster as #63025, #50982, #73526, #53717.
**Corroborating report with a root-cause clue: the session registry entry carries a different session ID than the on-disk transcript, so a lookup by registry ID finds nothing.**
Environment
Linux 6.18.33.2-microsoft-standard-WSL2, x86_64)CLAUDE_CODE_ENTRYPOINT=claude-desktopcwd=/home/<user>/devEvidence of the ID mismatch
A remote session created from the desktop app shows an intact list entry but an empty message list. Querying the session registry (via the session-management MCP from a sibling session on the same remote host):
There is no transcript file for
1aa7a0d1…under~/.claude/projects/on the remote host. The actual transcript lives under a different UUID:The creation/last-activity timestamps line up to the second, so these are unambiguously the same session under two IDs: the registry (which the desktop UI and the session-management
list_eventsAPI resolve by) holds one ID, while the transcript was written under another.list_eventsfor the registry ID returns0 of 0 messages; the UI shows the same emptiness.This would explain the "context preserved but UI empty" behavior upthread: whatever resolves the live backend finds the real session, but anything that resolves through the registry ID → transcript-file path finds nothing.
Workaround
claude --resume 1efe9748-…on the remote host loads the full history into a continuation session, which then registers correctly and is visible from the desktop app afterwards. The original registry entry remains a dead pointer.Confirming I'm hitting this too on macOS. Several sessions in the sidebar (with real, non-trivial diffs visible in the footer bar, e.g. "+22,816 -624" on a branch) open to a blank "No messages yet" pane instead of the transcript. It's reproducible and has persisted across multiple full app restarts. My workflow matches the description here: I have Claude Code running both locally on a Mac and via SSH from a second machine against the same repo, so this is very likely the remote/SSH-session hydration case described in the summary — local-only sessions for me do reload fine.
I reproduced the same symptom and was able to identify and fix the cause in my environment.
This may not explain every report in this issue, but it appears to be a reproducible failure mode for SSH connections configured with password-only authentication.
Environment
1.25927.0 (003700)2026-08-04T05:34:55.000Z2.1.221claude-desktopWhen reopening an existing remote session, the session title was still visible, but the message pane displayed:
The backend process was launched with the original session ID:
The previous context was also preserved. The backend could still understand and summarize the earlier conversation even though the Desktop UI displayed no messages.
Initial investigation
Because the remote transcript was intact while the UI was empty, I initially considered several possible causes:
ccd-cliwas reading the transcript for model context but not emitting historical messages as replay events.server --servewas dropping replay events before sending them throughrpc.sock.server --bridgewas not forwarding the events to Claude Desktop.The remote transcript was intact
The transcript existed under the expected project directory:
The filename matched the session ID passed to
ccd-cli --resume.The JSONL file contained the previous user and assistant messages, and the internal
sessionIdvalues matched the filename.For example:
This ruled out:
The remote server and RPC connection were healthy
The expected remote processes were running:
The Unix socket was both listening and connected:
The process file descriptors showed the expected topology:
The control channel between
server --serveandccd-cliwas also working.For example, the server sent an MCP configuration request:
And
ccd-clireturned a successful response:This ruled out a dead remote server, a broken Unix socket, or an unresponsive
ccd-cliprocess.straceconfirmed thatccd-cliread the complete transcriptI traced the cold-resume path using
strace.The resumed process opened the correct transcript and read it completely:
The final
read() = 0confirms that the file was read to EOF.At that point, the state was:
This initially made it look as though the CLI was using the JSONL only to restore model context without replaying the historical messages to the Desktop UI.
It was not a symlink or transcript discovery issue
I also checked whether
~/.claude/projectsor one of its parent paths was a symlink that the transcript discovery code might not follow.Both normal
findand symlink-followingfind -Lreturned the same transcript:Both resolved to the same path:
Therefore, this was not caused by symlink traversal or transcript discovery failure.
The actual cause was visible in the macOS Desktop logs
The Claude Desktop logs showed that Desktop attempted to synchronize the remote transcript:
Immediately afterward, it repeatedly logged:
This was the key clue.
The initial SSH connection used password authentication and worked because Claude Desktop displayed an interactive password prompt.
However, transcript synchronization and transcript tailing appear to use a separate background or non-interactive SSH process.
That process could not display a password prompt, so authentication failed.
The effective flow in my environment was:
This explains why all of the following could be true at the same time:
ccd-cli --resumelaunched normally,The transcript was not missing from the remote host. The separate SSH connection responsible for syncing or tailing it could not authenticate.
Resolution
I configured public-key authentication for the remote host.
After installing the public key on the remote server, I verified that non-interactive SSH authentication succeeded:
The expected result is:
No password prompt or other interactive authentication should be required.
I then fully quit Claude Desktop, reopened it, reconnected to the same remote host, and opened the same existing session.
The previous messages were displayed normally in the Desktop UI.
No transcript repair, session migration, JSONL modification, or session fork was required.
Conclusion
In my case, the root cause was:
Configuring public-key authentication resolved the issue immediately.
This is probably not the only possible cause of this symptom. Other comments describe separate failure modes, such as a mismatch between the session registry ID and the transcript ID.
However, password-only SSH authentication appears to be a reproducible cause that produces almost identical user-visible behavior.
Suggested improvements
1. Reuse the authenticated SSH connection
If possible, transcript byte-sync and tailing should reuse the SSH transport that Claude Desktop has already authenticated.
Currently, the initial password-authenticated connection can succeed while a separate non-interactive SSH process used for transcript synchronization fails. This leaves the remote backend fully functional but prevents the Desktop UI from loading the message history.
2. Surface the authentication failure in the UI
Currently, the UI only displays:
This makes the transcript appear empty or corrupted, even though the actual failure is SSH authentication during transcript synchronization.
A more accurate error would be something like: