Bug: claude -p gets 402 billing error when spawned by OpenClaw gateway but works from all other contexts
Summary
Claude Code CLI (claude -p) returns 402 "You're out of extra usage" when spawned by the OpenClaw gateway process, but the exact same command with identical env/args/credentials works from every other context: terminal, standalone Node.js, Paperclip (which also uses --print), and even fully isolated launchctl submit jobs.
This appears to be server-side discrimination against a specific open-source orchestration tool while honoring identical usage patterns from other tools.
Environment
- Claude Code: 2.1.100
- macOS Darwin 25.4.0 (Mac mini M4 Pro)
- Subscription: Max (
max_20x) - Auth:
claude.aiOAuth (logged in, valid) - OpenClaw: 2026.4.9
The Issue
The claude-cli backend in OpenClaw spawns claude -p --output-format stream-json --verbose --model opus — identical to how Paperclip spawns Claude (--print - --output-format stream-json --verbose). Paperclip works. OpenClaw doesn't.
What works (subscription billing, no errors)
| Context | Command | Result |
|---------|---------|--------|
| Terminal | echo "test" \| claude -p --model claude-opus-4-6 | ✅ Works |
| Terminal with all gateway flags | Same args + --strict-mcp-config --append-system-prompt --session-id | ✅ Works |
| Node.js child_process.spawn() with exact gateway env (54 vars) | Identical to gateway | ✅ Works |
| Node.js with detached: true + 21K system prompt + MCP config | Full reproduction | ✅ Works |
| launchctl submit (fully isolated OS process) | Same command | ✅ Works |
| Paperclip adapter (also uses --print) | --print - --output-format stream-json | ✅ Works |
| CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST=1 from terminal | Same command + env var | ✅ Works |
What fails (402 "extra usage" billing)
| Context | Result |
|---------|--------|
| OpenClaw gateway supervisor.spawn() | ❌ 402 |
| Direct child_process.spawn() bypass inside the gateway process | ❌ 402 |
| Bash wrapper (exec claude "$@") spawned by gateway | ❌ 402 |
| Node.js shim spawned by gateway | ❌ 402 |
| launchctl submit shim triggered by the gateway | ❌ 402 |
CLI stderr from gateway-spawned process
Loaded cached credentials.
Attempt 1 failed: You have exhausted your capacity on this model.. Retrying after 10000ms...
Attempt 2 failed: You have exhausted your capacity on this model.. Retrying after 10000ms...
Attempt 3 failed: You have exhausted your capacity on this model.. Max attempts reached
Investigation
We dumped the exact env the gateway passes to the spawned Claude process (54 variables), saved it to a file, loaded it in a standalone Node.js script, and spawned Claude with identical args. It works perfectly. The env is not the cause.
We tested every variable in isolation:
CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST— not the cause (works from terminal with it set)OPENCLAW_CLI=1— not the causeCLAUDECODE=1— not the cause- All
OPENCLAW_MCP_*vars — not the cause --strict-mcp-config --mcp-configwith OpenClaw MCP server — not the cause--append-system-promptwith 21K chars — not the causedetached: truespawn — not the cause- Process supervisor vs direct spawn — not the cause
- Complete
launchctlprocess isolation — not the cause
Questions
- What server-side detection mechanism causes identical CLI invocations to receive different billing classifications? The env, args, binary, and credentials are provably identical.
- Why does Paperclip (which also uses
--print) get subscription billing while OpenClaw gets "extra usage"? Both are open-source orchestration tools spawning the same CLI binary.
- Is the
CLAUDE_CODE_PROVIDER_MANAGED_BY_HOSTenv var intended to change billing classification? If so, this should be documented. We submitted a PR (openclaw/openclaw#64023, merged) to allow opt-out, but removing it doesn't fix the issue.
- Is there a mechanism by which the Claude CLI process detects it's inside a specific gateway process and reports this to the API? Our testing shows the issue is specific to the OpenClaw gateway process — even isolated subprocesses fail when triggered by the gateway.
Impact
This prevents Max/Pro subscribers from using their paid subscription capacity through OpenClaw, a popular open-source AI gateway. Users are forced to either:
- Pay "extra usage" fees for capacity they've already paid for
- Use alternative models (GPT, Gemini) through OpenClaw
- Use a different orchestration tool (Paperclip) that Anthropic apparently allows
This creates an uneven playing field where Anthropic's billing system favors certain open-source tools over others for identical usage patterns.
Related
- openclaw/openclaw#64023 (merged) — Added
hostManaged: falseconfig option - Tested on OpenClaw 2026.4.8 and 2026.4.9
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗