[BUG] claude --remote-control collapses into an implicit --print mode and exits immediately when no pseudo-terminal is present (e.g. under systemd)
Environment
- Claude Code CLI v2.1.210
- Linux, headless (no Desktop app, no tmux/screen, no
script) - Auth: claude.ai subscription login (not API key)
Summary
claude --remote-control "<name>" only works when stdin/stdout/stderr are connected to a real pseudo-terminal (a real terminal, or one provided via script, tmux, screen, etc.). Without any PTY at all — e.g. when launched directly as a systemd Type=simple service, or with all three file descriptors redirected to files//dev/null — the process does not start the Remote Control UI. Instead it appears to fall back to an implicit --print/non-interactive mode and exits immediately with an unrelated error message, rather than the interactive Remote Control session the flag requests.
Steps to reproduce
Minimal, fully isolated repro (no systemd needed):
cd ~ # or any project directory
claude --remote-control "test" < /dev/null > /tmp/out.log 2>&1 &
wait
cat /tmp/out.log
Observed behavior
Error: Input must be provided either through stdin or as a prompt argument when using --print
Exit code 1, immediately (well under a second). No Remote Control session is created, no session URL is printed.
The identical command run under a systemd Type=simple unit (ExecStart=/path/to/claude --remote-control "name", default systemd stdio — none of stdin/stdout/stderr are a TTY) fails the same way, with the same error, confirming this is not systemd-specific but purely about the absence of a PTY.
Contrast case (works correctly)
Wrapping the exact same command in a PTY makes it work as expected:
script -qefc 'claude --remote-control "test"' /tmp/out.log
This starts normally and prints a working https://claude.ai/code/session_... URL.
Expected behavior
Either:
--remote-controlshould work without requiring a real PTY (this is presumably how it needs to run under any process supervisor — systemd, Docker, etc. — none of which normally allocate a TTY for a service), or- if a PTY is a hard requirement for Remote Control, that requirement should be documented, and the CLI should fail with a clear, specific error naming the actual problem ("Remote Control requires a TTY") instead of silently and confusingly falling back to
--printsemantics and printing an error that talks about--print, a flag the user never passed.
Impact
This is what forces anyone who wants to run --remote-control under a process supervisor (systemd, Docker, any unattended/headless environment) to work around it via a manual PTY shim like script -qefc '...' logfile, which is undocumented, fragile, and not obviously the "supported" way to run Remote Control unattended. It's also the root cause that makes the "silent hang on --resume with an expired session" bug (reported separately) harder to diagnose, since the underlying command's TTY requirement isn't surfaced anywhere in the docs.
Related (found while searching for duplicates before filing)
- #39970 — Desktop-app-focused, closed as "not planned", touches on remote session resume/timeout but not this specific CLI/no-PTY collapse.
- #60790 — Desktop-app-focused, closed as duplicate, same broader "waits indefinitely instead of failing/reconnecting cleanly" pattern but a different code path (Desktop bridge, not CLI
--remote-controlinvocation).
Neither covers the CLI-only, no-Desktop, no-PTY case described here.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗