[BUG] Claude CLI Hangs Without TTY Despite Using `-p` Flag
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
- OS: macOS Darwin 24.6.0
- Claude Code Version: 2.0.8
- Java Version: OpenJDK 23.0.2
- Execution Context: Java ProcessBuilder spawning Claude subprocess
- TTY Status: No TTY (
psshowsTTY = ??)
Problem Description
When running claude -p '<prompt>' from a Java application using ProcessBuilder:
- Claude process spawns successfully
- Process hangs indefinitely (no output, no termination)
- Process must be killed after timeout (30s in our case)
- Same command works perfectly when run manually in terminal
What Should Happen?
Expected Behavior
claude -p should:
- Execute the prompt non-interactively
- Print the response to stdout
- Exit with code 0
- Work without a TTY (as documented for print mode)
Actual Behavior
claude -p:
- Spawns successfully
- Hangs indefinitely
- Produces no stdout or stderr
- Must be forcibly terminated
Error Messages/Logs
Steps to Reproduce
Reproduction Steps
1. Terminal Execution (Works)
cd /path/to/working/dir
claude -p 'what is 2+2'
# Output: 4
# Exits immediately
2. Java ProcessBuilder Execution (Hangs)
ProcessBuilder processBuilder = new ProcessBuilder("claude", "-p", "what is 2+2")
.directory(workingDir)
.redirectErrorStream(false);
Process process = processBuilder.start();
boolean completed = process.waitFor(30, TimeUnit.SECONDS);
// completed = false (timeout after 30 seconds)
// No stdout, no stderr
3. Verification: Agent-app has no TTY
ps -o pid,tty,state,command -p <agent-pid>
# PID TTY STAT COMMAND
# 76254 ?? SN /usr/bin/java ...agent-app.jar
4. Verification: Claude process has no TTY
ps -o pid,ppid,tty,state,command -p <claude-pid>
# PID PPID TTY STAT COMMAND
# 78903 76254 ?? S+ claude -p what is 2+2
Expected Behavior
claude -p should:
- Execute the prompt non-interactively
- Print the response to stdout
- Exit with code 0
- Work without a TTY (as documented for print mode)
Actual Behavior
claude -p:
- Spawns successfully
- Hangs indefinitely
- Produces no stdout or stderr
- Must be forcibly terminated
Investigation Findings
What We Tried
- ✅ Removed JAVA_HOME - Ensured system
/usr/bin/javais used (same as terminal) - ✅ Cleaned PATH - Matched terminal environment exactly
- ✅ Environment variables - Set SHELL, HOME, USER, TMPDIR, LANG
- ✅ MCP config - Converted paths to absolute
- ✅ Killed suspended processes - Removed old suspended MCP servers
- ✅ Tested without MCP - Simple
claude -p 'what is 2+2'also hangs
Evidence
2025-10-06T16:26:52.660+01:00 INFO ClaudeCommandService : Command: [claude, -p, what is 2+2]
2025-10-06T16:26:52.660+01:00 INFO ClaudeCommandService : Working Dir: /Users/.../68dac182f208810fecebe9b2
2025-10-06T16:26:52.660+01:00 INFO ClaudeCommandService : JAVA_HOME: null
2025-10-06T16:26:52.660+01:00 INFO ClaudeCommandService : PATH: /opt/anaconda3/bin:...
2025-10-06T16:26:52.660+01:00 INFO ClaudeCommandService : SHELL: /bin/zsh
2025-10-06T16:26:52.665+01:00 INFO ClaudeCommandService : Claude process started with PID: 78903
2025-10-06T16:27:22.670+01:00 WARN ClaudeCommandService : Claude process timed out after 30s; destroying...
Related Issues
- Similar TTY issue with tools: https://github.com/anthropics/claude-code/issues/8078
- That issue is about tools Claude runs; ours is about Claude CLI itself
Workarounds Considered
- PTY (pty4j) - Creates pseudo-terminal but risks SIGTTIN for MCP subprocesses
scriptcommand - macOS utility to fake TTY:script -q /dev/null claude -p '...'unbuffer(expect) - Similar TTY simulation
Use Case
Building an infrastructure monitoring agent that:
- Runs as background service (no TTY)
- Executes Claude Code commands on behalf of users
- Needs to integrate with MCP servers for task management
- Must work non-interactively in automation scenarios
Impact
- Severity: High - Blocks programmatic/automated use of Claude CLI
- Scope: Affects any non-TTY execution context (daemons, CI/CD, batch jobs, etc.)
- Workaround: None that properly solves MCP integration
Request
Please make claude -p mode truly non-interactive and TTY-independent as the flag suggests. The -p flag documentation implies it should work for scripting/automation, but it currently requires a TTY to function.
System Information
# macOS
Darwin 24.6.0
# Claude Code version
2.0.8 (Claude Code)
# Java
openjdk version "23.0.2"
# Terminal
/bin/zsh
Additional Context
This investigation took several hours and multiple approaches to isolate the issue. We initially suspected:
- Path resolution issues
- JAVA_HOME conflicts
- MCP configuration problems
- SIGTTIN signals from TTY inheritance
But ultimately proved that even the simplest claude -p command hangs without a TTY, indicating a fundamental issue with the CLI's TTY handling.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
claude --version 2.0.8 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗