Summary
claude-code-action@v1 (CLI native build 2.1.165, @anthropic-ai/claude-agent-sdk@0.3.165) hangs indefinitely on a GitHub-hosted ubuntu-latest runner when authenticated with claude_code_oauth_token. The spawned claude process emits zero bytes of output and the job runs until the workflow timeout-minutes kills it (The operation was canceled.). This reproduces consistently across multiple runs.
I have isolated the cause to the CLI runtime / OAuth bootstrap path, not auth, rate limits, or network — see the proof below.
Environment
- Runner: GitHub-hosted
ubuntu-latest
- Action:
anthropics/claude-code-action@v1
- Installed:
Claude Code native build 2.1.165, @anthropic-ai/claude-agent-sdk@0.3.165
- Auth:
claude_code_oauth_token (subscription OAuth token from claude setup-token)
- Mode: auto-detected
agent
What I observe
The step log ends at:
Running Claude with prompt from file: .../claude-prompt.txt
SDK options: { "systemPrompt": {...}, "pathToClaudeCodeExecutable": "/home/runner/.local/bin/claude", "settingSources": ["user","project","local"] }
<-- 15 minutes of complete silence, zero output -->
##[error]The operation was canceled.
This is unaffected by:
show_full_output: true
--debug in claude_args
DISABLE_AUTOUPDATER=1, DISABLE_TELEMETRY=1, DISABLE_ERROR_REPORTING=1, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
In every case the claude process produces no output whatsoever before the timeout.
Proof that token / account / network are fine
In the same job, immediately before the action step, I ran two curl probes from the runner using the exact same OAuth token:
1. Reachability (unauthenticated):
POST https://api.anthropic.com/v1/messages (no auth)
-> http=401 connect=0.005s total=0.10s
body: {"type":"error","error":{"type":"authentication_error","message":"x-api-key header is required"}}
Egress to the API is open and fast.
2. Authenticated minimal call with the OAuth token:
POST https://api.anthropic.com/v1/messages
-H "anthropic-version: 2023-06-01"
-H "anthropic-beta: oauth-2025-04-20"
-H "authorization: Bearer $CLAUDE_CODE_OAUTH_TOKEN"
-d '{"model":"claude-haiku-4-5-20251001","max_tokens":1,"messages":[{"role":"user","content":"hi"}]}'
-> http=200 total=0.93s
body: {"model":"claude-haiku-4-5-...","content":[{"type":"text","text":"Hi"}], ...}
So the token is valid, not rate-limited, and the API responds in under 1s — yet the claude CLI spawned by the action hangs for 15 minutes on the same runner with the same token.
Hypothesis
Because a raw authenticated API call works instantly but the CLI hangs with zero output, the stall appears to be in the CLI's credential/OAuth bootstrap on a headless runner (e.g. blocking on an OS keyring / credential store that does not exist or has no unlocked daemon). curl bypasses that entire path, which is why it succeeds.
Questions
- Is
claude_code_oauth_token expected to work on headless GitHub-hosted runners with native build 2.1.165, or is anthropic_api_key the supported path for CI?
- Is there an env var to force the CLI to skip the OS keyring / credential store and use the provided token directly?
- Can the CLI fail fast (or log) instead of hanging silently when the credential bootstrap blocks?
Happy to provide full (sanitized) workflow logs.
Summary
claude-code-action@v1(CLI native build2.1.165,@anthropic-ai/claude-agent-sdk@0.3.165) hangs indefinitely on a GitHub-hostedubuntu-latestrunner when authenticated withclaude_code_oauth_token. The spawnedclaudeprocess emits zero bytes of output and the job runs until the workflowtimeout-minuteskills it (The operation was canceled.). This reproduces consistently across multiple runs.I have isolated the cause to the CLI runtime / OAuth bootstrap path, not auth, rate limits, or network — see the proof below.
Environment
ubuntu-latestanthropics/claude-code-action@v1Claude Code native build 2.1.165,@anthropic-ai/claude-agent-sdk@0.3.165claude_code_oauth_token(subscription OAuth token fromclaude setup-token)agentWhat I observe
The step log ends at:
This is unaffected by:
show_full_output: true--debuginclaude_argsDISABLE_AUTOUPDATER=1,DISABLE_TELEMETRY=1,DISABLE_ERROR_REPORTING=1,CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1In every case the
claudeprocess produces no output whatsoever before the timeout.Proof that token / account / network are fine
In the same job, immediately before the action step, I ran two
curlprobes from the runner using the exact same OAuth token:1. Reachability (unauthenticated):
Egress to the API is open and fast.
2. Authenticated minimal call with the OAuth token:
So the token is valid, not rate-limited, and the API responds in under 1s — yet the
claudeCLI spawned by the action hangs for 15 minutes on the same runner with the same token.Hypothesis
Because a raw authenticated API call works instantly but the CLI hangs with zero output, the stall appears to be in the CLI's credential/OAuth bootstrap on a headless runner (e.g. blocking on an OS keyring / credential store that does not exist or has no unlocked daemon).
curlbypasses that entire path, which is why it succeeds.Questions
claude_code_oauth_tokenexpected to work on headless GitHub-hosted runners with native build2.1.165, or isanthropic_api_keythe supported path for CI?Happy to provide full (sanitized) workflow logs.