Skip to content

[BUG] Bash tool children inherit the TUI's real pty; ssh passphrase prompt breaks fullscreen mouse tracking and wedges the session across resumes (regression in 2.1.281) #97297

Description

@lizthegrey

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • I am using the latest version of Claude Code

What's Wrong?

Child processes run by the Bash tool inherit the real pty that the Claude Code TUI is running on, so they can open it as /dev/tty and change its modes. In fullscreen mode (mouse tracking on), this corrupts the UI's terminal state.

It's easy to trigger with ssh. If the Bash tool runs ssh (directly or via git over SSH) and the private keys in ~/.ssh are not loaded into an agent, ssh finds a controlling terminal, opens /dev/tty (the UI's real pty) and prints its own Enter passphrase for key ... prompt there, changing the termios modes (echo off, etc.) to read the passphrase. Then:

  1. The terminal's modes get changed underneath Claude Code, and mouse tracking stops working. Keystrokes are no longer read correctly and raw escape sequences (mouse reports and similar) are printed to the screen as garbage.
  2. The passphrase prompt doesn't work either: ssh and the Claude Code UI are both reading the same tty, so the prompt can't be answered and ssh fails.
  3. The session can't be recovered. Resuming it reattaches to the same pty in the same broken state, so the session stays wedged across resumes.

I first saw this in 2.1.281 and never saw it in 2.1.280 or earlier, so something about how Bash-tool children are spawned (controlling terminal / session / stdio) seems to have regressed.

What Should Happen?

  • Bash-tool child processes should not get the real pty as their controlling terminal. They should run in their own session (setsid) with no controlling tty, or with a separate pty, so /dev/tty either isn't available or isn't the UI's terminal. Then ssh fails cleanly (e.g. Permission denied (publickey) or "no tty present") without touching the UI.
  • Resuming a session should reset the terminal state (re-enable mouse tracking, alt screen, etc.) instead of reattaching to a pty stuck in a bad state.

Error Messages/Logs

Garbage on screen consists of raw mouse/escape-sequence reports mixed with ssh's passphrase prompt; no usable error is shown.

Steps to Reproduce

  1. On Linux, have passphrase-protected keys in ~/.ssh with no running ssh-agent holding them (for example ssh-add -l → no identities / no agent).
  2. Start Claude Code 2.1.281+ in fullscreen mode (mouse tracking on).
  3. Ask Claude to run something that uses SSH auth, for example ssh somehost true or git fetch against an [email protected]: remote.
  4. Observe: ssh writes its terminal passphrase prompt to the UI's tty, mouse tracking stops working, input stops working, escape-sequence garbage fills the screen and ssh fails.
  5. Exit or detach and resume the session. It comes back in the same broken state.

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

2.1.280

Claude Code Version

2.1.282 (Claude Code)

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

Reproduces in both iTerm2 on macOS (ssh'd into the Linux host) and the ChromeOS Terminal app. TERM=xterm-256color, bash.

Additional Information

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions