Interactive mode exits immediately (exit 0) on Linux kernel 4.18 (Kubernetes/RHEL 8)

Status Fixed / completed
Maintainer reply None cached
Activity 6 comments · opened Mar 6, 2026 · closed Mar 16, 2026

Description

Claude Code interactive mode starts, renders the TUI welcome screen with REPL prompt (), then immediately exits with code 0 within ~1 second. Non-interactive mode (claude -p "prompt") works correctly.

Environment

  • Claude Code: v2.1.70 (also reproduced on v2.1.58)
  • OS: Ubuntu 24.04.3 LTS container on Kubernetes
  • Host Kernel: 4.18.0-305.131.1.el8_4.x86_64 (RHEL/CentOS 8)
  • Platform: TWCC (Taiwan Computing Cloud) — HPC/GPU cluster
  • Memory: 754GB (not OOM)
  • glibc: 2.39
  • TTY: Valid /dev/pts/X via tmux, terminal size 36×120

Steps to Reproduce

  1. SSH into a Kubernetes pod running on a RHEL 8 host (kernel 4.18)
  2. Start tmux (or any terminal with a valid PTY)
  3. Run claude or claude --dangerously-skip-permissions
  4. Complete the trust prompt (select "Yes, I trust this folder")
  5. Result: Welcome screen renders, REPL prompt appears, process exits with code 0

Key Findings

| Test | Result |
|------|--------|
| claude --version | Works |
| claude -p "hello" | Works |
| claude (interactive) | Exits immediately after REPL renders |
| Trust prompt | Stays alive (blocking input) |
| After trust confirmation | Exits within ~1s |
| Node.js stdin.resume() on same system | Keeps event loop alive correctly |

strace evidence

  • io_uring_setup (syscall 425) returns ENOSYS — kernel 4.18 has stubs but no implementation (io_uring was introduced in kernel 5.1)
  • Bun falls back to epoll, but epoll_wait runs only 1 time before event loop drains
  • Main process never reads from stdin (fd 0) — stdin watcher appears unregistered
  • Process sends SIGPWR to itself (Bun internal signal), removes all epoll watchers, then exit_group(0)

Debug log

[REPL:mount] REPL mounted, disabled=false
performStartupChecks called
AutoUpdaterWrapper: Installation type: native
Ripgrep first use test: PASSED

REPL mounts successfully, no errors logged, then process exits silently.

What was ruled out

  • PTY/terminal issues (valid PTY, correct TERM, correct dimensions)
  • VS Code shell integration (reproduced in plain tmux)
  • Auth/OAuth (token valid, --print mode works)
  • Environment variables (reproduced with env -i clean env)
  • Auto-update (CLAUDE_CODE_DISABLE_AUTOUPDATE=1 — same result)
  • Multiple versions (v2.1.58 and v2.1.70)
  • expect wrapper with separate PTY — same exit
  • BUN_FEATURE_FLAG_FORCE_WAITER_THREAD=1 — no effect

Full Diagnostic Report

Gist with debug logs, strace output, and environment info:
https://gist.github.com/thc1006/2bb7392607c524df67ecd24cae98bc67

Hypothesis

Bun runtime's event loop does not properly maintain stdin watchers when io_uring_setup returns ENOSYS on kernels < 5.1. The epoll fallback appears incomplete — the event loop determines there are no active handles after one iteration and drains, causing a clean exit.

Impact

Kernel 4.18 (RHEL/CentOS 8) is widely used in enterprise HPC and Kubernetes environments. Interactive mode is unusable on these systems. Only claude -p (non-interactive) works.

View original on GitHub ↗

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