SSH sessions: history blank and fork fails due to tail connecting via raw IP instead of SSH config alias

Resolved 💬 2 comments Opened Jun 29, 2026 by mannmann2 Closed Jul 3, 2026

Summary

When using Claude Code over SSH in the desktop app, two related features break after restarting the app:

  1. Session history vanishes — previously active sessions appear blank on the sidebar
  2. Forking SSH sessions fails — cannot fork/branch a conversation that was held over SSH

Both issues share the same root cause.

Root Cause

The desktop app runs two separate SSH operations when opening a previous SSH session:

  • Byte-sync — downloads the session transcript (.jsonl) from the remote server. Uses the SSH config hostname alias (e.g. dash), so IdentityFile and other SSH config settings are applied correctly. Works.
  • Tail — a persistent connection to stream live updates. Resolves the hostname to its raw IP (e.g. root@62.238.23.200) and connects directly, bypassing the SSH config entirely. This means IdentityFile, User, and other per-host settings are not applied. Always fails.

Log evidence (repeating every ~30–60 seconds):

[warn] [SSH] Failed to tail remote transcript: root@62.238.23.200: Permission denied (publickey,password).

Because the tail connection never succeeds, the app does not render existing history (even though the byte-synced transcript data is present in the local session JSON under completedTurns). The same tail failure also blocks session forking.

Steps to Reproduce

  1. Set up an SSH remote in Claude desktop app using an SSH config alias (e.g. Host dash with HostName <ip> and IdentityFile ~/.ssh/id_ed25519)
  2. Start a Claude Code session over SSH and have a conversation
  3. Restart the Claude desktop app
  4. Open the previous SSH session from the sidebar → history is blank
  5. Attempt to fork the session → fails

Expected Behavior

  • Session history should display from the locally cached completedTurns data even before the tail connection is established
  • The tail connection should use the SSH config alias (not the resolved raw IP) so that IdentityFile and other settings apply
  • Forking SSH sessions should work

Workaround

Add the raw IP as an additional Host alias in ~/.ssh/config so SSH config rules apply to both hostname and direct IP connections:

Host dash 62.238.23.200
  HostName 62.238.23.200
  User root
  IdentityFile ~/.ssh/id_ed25519
  AddKeysToAgent yes
  UseKeychain yes

Then run ssh-add --apple-use-keychain ~/.ssh/id_ed25519 to load the key into the macOS Keychain.

Environment

  • Platform: macOS (darwin 25.5.0)
  • SSH config: hostname alias with IdentityFile (passphrase-protected key)
  • SSH agent: empty on shell launch (key not pre-loaded)

Additional Notes

The session metadata (stored locally in ~/Library/Application Support/Claude/claude-code-sessions/) correctly records sshRemoteTranscriptPath pointing to the remote .jsonl file, and completedTurns is populated after a successful byte-sync. The data is there — the display/fork failure is a UI-layer dependency on the tail connection that should be decoupled.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗