[BUG] Remote SSH daemon (ccd-cli/2.1.111) exits with code 1 on initialize when hookCallbackIds are present

Resolved 💬 4 comments Opened Apr 19, 2026 by stefanogalbusera-valkyriastudio Closed Jun 2, 2026

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?

Environment

  • Client: Claude Desktop app on Windows 11 (PowerShell 5.1)
  • Server: Ubuntu 24.04 LTS (x86_64), kernel 6.x, on Hetzner VM
  • Claude Code version (local daemon): 2.1.111
  • Claude Code version (system claude): 2.1.91
  • Node.js: v18.19.1 on server
  • Auth: Claude Max (OAuth)

Summary

When connecting to a remote SSH machine via the "SSH connection" feature (Claude Code tab → new SSH connection), the daemon at /root/.claude/remote/ccd-cli/2.1.111 exits with code 1 immediately after receiving the initialize control_request, if the payload contains hookCallbackIds.

Reproduction

  1. Configure an SSH connection in Claude Code tab of Claude Desktop
  2. Connect to the remote host (auth and SSH work fine — confirmed via ssh -v)
  3. Send any user prompt (e.g. ls)
  4. "Claude Code process exited with code 1" is shown, no output visible

Captured payload (intercepted via wrapper script)

\``json
{"request_id":"s4kd7qgugm","type":"control_request","request":{"subtype":"initialize","hooks":{"PreToolUse":[{"matcher":"mcp__ccd_directory__request_directory","hookCallbackIds":["hook_0"]},{"matcher":"mcp__.*","hookCallbackIds":["hook_1"]}],"Stop":[{"hookCallbackIds":["hook_2"]}]}}}
\
``

Observations

  • The daemon works correctly when invoked standalone (ssh -t hetzner "claude" works).
  • The daemon works correctly when the same payload is sent with empty hooks ("hooks":{}).
  • stderr of the crashed process is empty (0 bytes) — no error message.
  • exit code is always 1.
  • Wrapper script that removes hookCallbackIds via jq lets the daemon start, but the process then hangs indefinitely (no output, keeps receiving pings but never produces a response) — suggesting the callback IDs are expected by the daemon's RPC loop.

Workaround

Currently using ssh hetzner + claude interactively via tmux instead of the UI feature.

What Should Happen?

SHould establish a ssh connection that doesn't crash at the first input

Error Messages/Logs

Steps to Reproduce

Just creating an ssh connection to a server, using pub key instead of psw

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.111

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

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