claude ssh <config> leaks 'ssh' as first user prompt on remote session

Resolved 💬 3 comments Opened Mar 25, 2026 by ajwcontreras Closed Mar 25, 2026

Bug

When running claude ssh <config>, the remote Claude Code session receives ssh as the first user message/prompt. This happens because the native binary handles the SSH connection but doesn't strip ssh from argv before the JS layer processes it on the remote side.

Steps to Reproduce

  1. Configure an SSH target in ~/.claude/settings.json:
{
  "sshConfigs": [
    {
      "id": "my-server",
      "name": "My Server",
      "sshHost": "user@1.2.3.4",
      "sshIdentityFile": "~/.ssh/my_key"
    }
  ]
}
  1. Run:
claude ssh my-server
  1. Observe the remote session immediately shows ssh as the first user message before you type anything:
❯ ssh
⏺ Looking at the SSH targets from CLAUDE.md...

Root Cause

From investigating the minified cli.js (v2.1.81):

  • There is no ssh subcommand registered in Commander.js. The registered subcommands are: mcp, auth, plugin, setup-token, agents, auto-mode, remote-control, doctor, update, install.
  • The main program defines [prompt] as an optional positional argument: .argument("[prompt]", "Your prompt", String)
  • Since ssh doesn't match any subcommand, Commander.js treats it as the [prompt] positional value
  • This flows into initialMessage in interactive mode: initialMessage: F6 ? {message: F8({content: String(F6)})} : null
  • The string "ssh" gets auto-submitted as the first user message

There's already a precedent fix for this pattern — "code" is special-cased:

if(w==="code") Q("tengu_code_prompt_ignored",{}), console.warn(...), w=void 0;

Suggested Fix

Either:

  1. Add ssh to the existing guard: if(w==="code"||w==="ssh")
  2. Or register ssh as a proper Commander.js subcommand so it doesn't fall through to [prompt]

Workaround

A UserPromptSubmit hook in ~/.claude/settings.json can block the leaked prompt:

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/script.sh"
          }
        ]
      }
    ]
  }
}

Where script.sh reads stdin JSON, checks if the prompt field equals "ssh", and exits with code 2 to block it.

Environment

  • Claude Code v2.1.81
  • macOS (darwin arm64)
  • Using sshConfigs in settings.json

🤖 Generated with Claude Code

View original on GitHub ↗

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