[BUG] macOS deep links silently fail when the launch command exceeds 1024 bytes (tty MAX_INPUT truncation)

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 0 comments · opened Jul 26, 2026

Summary

The claude-cli://open handler on macOS launches sessions by injecting its launch command (<versioned cli path> --deep-link-origin --deep-link-repo=... --deep-link-cwd-b64=... --prefill-b64=<b64(prompt)>) into a freshly spawned terminal shell (iTerm2 write text / Terminal.app do script). That write races shell startup: while the tty is still in canonical mode, macOS discards input past MAX_INPUT (1024 bytes), including the trailing newline. The command sits truncated and unexecuted at a shell prompt, the terminal bell rings (IMAXBEL; a bell icon in the window title is the tell), and no session opens. The failure is completely silent from the user's perspective.

Repro

  • CLI 2.1.220, macOS (Darwin 25.5), iTerm2 + zsh (also reproduces with Terminal.app)
  • Any claude-cli://open deep link whose decoded q prompt is over roughly 700 characters: base64 expansion (4/3) plus the ~320-byte command prefix pushes the injected command past 1024 bytes
  • Result, verified live: truncation at exactly the 1024-byte boundary, command never executes, no session
  • The same link with a short q launches fine and shows the "Prompt from an external link" banner

Expected

The docs advertise a 5,000-character q cap for deep links. On macOS anything past ~700 characters silently fails, so the documented cap is unreachable.

Suggested fixes

  • Wait for shell readiness before injecting the command, or
  • Chunk the write so no single line exceeds MAX_INPUT, or
  • Pass the prefill via a temp file (or env var) instead of argv so the injected command stays short regardless of prompt size

Workaround we shipped

We now cap our deep links' decoded q at 500 UTF-8 bytes server-side and show the full prompt on the landing page for copy-paste. Works, but every integrator will hit this wall independently since the failure mode is silent.

View original on GitHub ↗