Auth errors in claude -p are written to stdout instead of stderr

Open 💬 0 comments Opened Jul 2, 2026 by ictechgy

Description

When claude -p / claude --print is used non-interactively, an authentication diagnostic can be emitted on stdout instead of stderr. In the minimal repro below, the process exits with rc=1, but the auth error is written to stdout and stderr is empty.

This is difficult for automation: wrappers commonly treat stdout as assistant output, so the auth diagnostic can be mistaken for a successful model response unless the wrapper also checks the exit code and special-cases known error strings.

Minimal reproduction

Use a throwaway working directory, throwaway config/home paths, and an intentionally invalid API key:

ANTHROPIC_API_KEY=<invalid> \
CLAUDE_CONFIG_DIR=<tmp>/config \
HOME=<tmp>/home \
claude --bare -p 'Say ok' >out 2>err

Observed result

rc=1
stdout: Invalid API key · Fix external API key
stderr: <empty>

Expected result

In non-interactive print mode, authentication failures should be written to stderr, leaving stdout reserved for successful assistant output.

A structured error format would also be useful for automation, but this report is intentionally narrower: auth diagnostics should not be delivered on the same stdout channel as model output.

Environment

  • Claude Code version: 2.1.198
  • Platform: macOS / Darwin arm64

Related issues checked

  • #35540 is related because it requests structured error output and exit-code differentiation for claude -p, but it is broader and currently closed/locked.
  • #69864 is related to headless/scheduled --print 401 behavior, but this report is specifically about stdout/stderr stream routing for auth diagnostics.

View original on GitHub ↗