[BUG] Claude Code GitHub Action fails silently during PR review (v2.1.49, agent mode, OIDC)

Resolved 💬 4 comments Opened Feb 21, 2026 by Noam2710 Closed Mar 22, 2026

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?

Description

When running Claude Code inside a GitHub Action for automated pull request review, the workflow installs successfully but then appears to hang or fail silently when invoking the SDK.

The installation and plugin setup complete without errors. However, when Claude is executed in agent mode for a pull_request event, the job stops after printing a partial JSON object and exits without producing a review or a structured error message.

This makes it difficult to determine whether the failure is related to authentication, agent mode execution, or SDK output handling.

Environment

  • Claude Code version: 2.1.49
  • Mode: agent
  • Event: pull_request
  • Authentication: OIDC → App token → GITHUB_TOKEN
  • Plugin: code-review@claude-code-plugins
  • Actor: verified human user with write/admin permissions
Run anthropics/claude-code-action@v1
Run oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3
Cache hit for: <redacted>
Received 14270606 of 35242126 (40.5%), 13.6 MBs/sec
Received 35242126 of 35242126 (100.0%), 29.3 MBs/sec
Cache Size: ~34 MB (35242126 B)
/usr/bin/tar -xf /home/runner/work/_temp/77897448-d113-4edc-a365-7fb347c81982/cache.tzst -P -C /home/runner/work/<redacted>/<redacted> --use-compress-program unzstd
Cache restored successfully
/home/runner/.bun/bin/bun --revision
1.3.6+d530ed993
Using a cached version of Bun: 1.3.6+d530ed993
Run cd ${GITHUB_ACTION_PATH}
bun install v1.3.6 (d530ed99)

+ @actions/core@1.11.1
+ @actions/github@6.0.1
+ @anthropic-ai/claude-agent-sdk@0.2.49
+ @modelcontextprotocol/sdk@1.16.0
+ @octokit/graphql@8.2.2
+ @octokit/rest@21.1.1
+ @octokit/webhooks-types@7.6.1
+ node-fetch@3.3.2
+ shell-quote@1.8.3
+ zod@3.25.76

138 packages installed [808.00ms]
Run bun run ${GITHUB_ACTION_PATH}/src/entrypoints/run.ts
Auto-detected mode: agent for event: pull_request
Requesting OIDC token...
Attempt 1 of 3...
OIDC token successfully obtained
Exchanging OIDC token for app token...
Attempt 1 of 3...
App token successfully obtained
Using GITHUB_TOKEN from OIDC
Checking permissions for actor: <redacted>
Permission level retrieved: admin
Actor has write access: admin
Mode: agent
Context prompt: /code-review:code-review <redacted>/<redacted>/pull/<redacted>
Trigger result: true
Preparing with mode: agent for event: pull_request
Actor type: User
Verified human actor: <redacted>
Configuring git authentication for non-signing mode
Configuring git user...
Setting git user as claude[bot]...
✓ Set git user as claude[bot]
Removing existing git authentication headers...
✓ Removed existing authentication headers
Updating remote URL with authentication...
✓ Updated remote URL with authentication token
Git authentication configured successfully
Installing Claude Code v2.1.49...
Installation attempt 1...
Setting up Claude Code...
^[[?2026h
Checkinginstallationstatus...
^[[?2026l^[[?2026h
Installing Clude Cde nive build2.1.49...
^[[?2026l^[[?2026h
Seting uplauncher and shellintegration. 
^[[?2026l^[[?2026h
✔ Claude Code successfully installed!       

Version:2.1.49

Location:~/.local/bin/claude


Next:Runclaude--helptogetstarted
^[[?2026l^[[?2026h
^[[?2026l
✅ Installation complete!

Claude Code installed successfully
Setting up Claude settings at: /home/runner/.claude/settings.json
Creating .claude directory...
No existing settings file found, creating new one
Updated settings with enableAllProjectMcpServers: true
Settings saved successfully
Adding 1 marketplace(s)...
Adding marketplace: https://github.com/anthropics/claude-code.git
Adding marketplace...
Refreshing marketplace cache…
Cloning repository: https://github.com/anthropics/claude-code.git
Clone complete, validating marketplace…
Cleaning up old marketplace cache…
✔ Successfully added marketplace: claude-code-plugins
✓ Successfully added marketplace: https://github.com/anthropics/claude-code.git
Installing 1 plugin(s)...
Installing plugin: code-review@claude-code-plugins
Installing plugin "code-review@claude-code-plugins"...
✔ Successfully installed plugin: code-review@claude-code-plugins (scope: user)
✓ Successfully installed: code-review@claude-code-plugins
Running Claude Code via SDK (full output hidden for security)...
Rerun in debug mode or enable `show_full_output: true` in your workflow file for full output.
Running Claude with prompt from file: /home/runner/work/_temp/claude-prompts/claude-prompt.txt
SDK options: {
  "systemPrompt": {
    "type": "preset",
    "preset": "claude_code"
  },
  "pathToClaudeCodeExecutable": "",
  "extraArgs": {},
  "settingSources": [
    "user",
    "project",
    "local"
  ]
}
{
  "type": "system",
  "subtype": "init",
  "message": "Claude Code initialized",
  "model": "claude-sonnet-4-6"
}
{
  "type": "result",
  "subtype": "success",
  "is_error": true,
  "duration_ms": 495,
  "num_turns": 1,
  "total_cost_usd": 0,
  "permission_denials": []
}
SDK execution error: 14 |     depsCount: ${X},
15 |     deps: ${Y}}`};var _j={keyword:"dependencies",type:"object",schemaType:"object",error:jB.error,code(Q){let[X,Y]=Tj(Q);MB(Q,X),AB(Q,Y)}};function Tj({schema:Q}){let X={},Y={};for(let $ in Q){if($==="__proto__")continue;let W=Array.isArray(Q[$])?X:Y;W[$]=Q[$]}return[X,Y]}function MB(Q,X=Q.schema){let{gen:Y,data:$,it:W}=Q;if(Object.keys(X).length===0)return;let J=Y.let("missing");for(let G in X){let H=X[G];if(H.length===0)continue;let B=(0,G9.propertyInData)(Y,$,G,W.opts.ownProperties);if(Q.setParams({property:G,depsCount:H.length,deps:H.join(", ")}),W.allErrors)Y.if(B,()=>{for(let z of H)(0,G9.checkReportMissingProp)(Q,z)});else Y.if(f$._`${B} && (${(0,G9.checkMissingProp)(Q,H,J)})`),(0,G9.reportMissingProp)(Q,J),Y.else()}}jB.validatePropertyDeps=MB;function AB(Q,X=Q.schema){let{gen:Y,data:$,keyword:W,it:J}=Q,G=Y.name("valid");for(let H in X){if((0,vj.alwaysValidSchema)(J,X[H]))continue;Y.if((0,G9.propertyInData)(Y,$,H,J.opts.ownProperties),()=>{let B=Q.subschema({keyword:W,schemaProp:H},G);Q.mergeValidEvalu
Error: Action failed with error: SDK execution error: Error: Claude Code process exited with code 1
16 | `))Q=k0(Q);let $=`${new Date().toISOString()} [${X.toUpperCase()}] ${Q.trim()}
17 | `;if(QW()){p7($);return}yV().write($)}function YW(){return XW()??process.env.CLAUDE_CODE_DEBUG_LOGS_DIR??e7(F9(),"debug",`${r7()}.txt`)}var gV=T1(()=>{if(process.argv[2]==="--ripgrep")return;try{let Q=YW(),X=s7(Q),Y=e7(X,"latest");if(!J1().existsSync(X))J1().mkdirSync(X);if(J1().existsSync(Y))try{J1().unlinkSync(Y)}catch{}J1().symlinkSync(Q,Y)}catch{}});var G2=(()=>{let Q=process.env.CLAUDE_CODE_SLOW_OPERATION_THRESHOLD_MS;if(Q!==void 0){let X=Number(Q);if(!Number.isNaN(X)&&X>=0)return X}return 1/0})();var hV={[Symbol.dispose](){}};function fV(){return hV}var V0=fV;function k0(Q,X,Y){let W=[];try{const $=$0(W,V0`JSON.stringify(${Q})`,0);return JSON.stringify(Q,X,Y)}catch(J){var G=J,H=1}finally{W0(W,G,H)}}var D9=(Q,X)=>{let $=[];try{const Y=$0($,V0`JSON.parse(${Q})`,0);return typeof X>"u"?JSON.parse(Q):JSON.parse(Q,X)}catch(W){var J=W,G=1}finally{W0($,J,G)}};var rV={cwd(){return process.cwd()},existsSync(Q){let Y=[];try{const X=$0(Y,V0`fs.existsSync(${Q})`,0);return f.existsSync(Q)}catch($){var W=$,J=1}finally
18 | `),O9}function w1(Q){let X=Yq();if(!X)return;let $=`${new Date().toISOString()} ${Q}
19 | `;eV(X,$)}function GW(Q,X){let Y={...Q};if(X){let $={sandbox:X};if(Y.settings)try{$={...D9(Y.settings),sandbox:X}}catch{}Y.settings=k0($)}return Y}class Y4{options;process;processStdin;processStdout;ready=!1;abortController;exitError;exitListeners=[];processExitHandler;abortHandler;constructor(Q){this.options=Q;this.abortController=Q.abortController||M6(),this.initialize()}getDefaultExecutable(){return b6()?"bun":"node"}spawnLocalProcess(Q){let{command:X,args:Y,cwd:$,env:W,signal:J}=Q,G=W.DEBUG_CLAUDE_AGENT_SDK||this.options.stderr?"pipe":"ignore",H=$q(X,Y,{cwd:$,stdio:["pipe","pipe",G],signal:J,env:W,windowsHide:!0});if(W.DEBUG_CLAUDE_AGENT_SDK||this.options.stderr)H.stderr.on("data",(z)=>{let K=z.toString();if(w1(K),this.options.stderr)this.options.stderr(K)});return{stdin:H.stdin,stdout:H.stdout,get killed(){return H.killed},get exitCode(){return H.exitCode},kill:H.kill.bind(H),on:H.on.bind(H),once:H.once.bind(H),off:H.off.bind(H)}}initialize(){try{let{additionalDirectories:Q=[],agent:X,betas:Y,cwd:$,execu

error: Claude Code process exited with code 1
      at Y (/home/runner/work/_actions/anthropics/claude-code-action/v1/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs:19:8125)
      at emit (node:events:98:22)
      at #handleOnExit (node:child_process:520:14)

Error: Process completed with exit code 1.
Run curl -L \
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0

What Should Happen?

Claude should complete the pull request review and post feedback.

If an error occurs, it should:

  • Emit a structured error message
  • Avoid truncating JSON output
  • Provide actionable diagnostics

Steps to Reproduce

  1. Create a GitHub Action workflow with the following configuration:
name: Claude Code

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
  issues:
    types: [opened, assigned]
  pull_request_review:
    types: [submitted]

jobs:
  claude:
    if: |
      (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
      (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: read
      issues: read
      id-token: write
      actions: read # Required for Claude to read CI results on PRs
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - name: Run Claude Code
        id: claude
        uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

          # This is an optional setting that allows Claude to read CI results on PRs
          additional_permissions: |
            actions: read

          # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
          # prompt: 'Update the pull request description to include a summary of changes.'

          # Optional: Add claude_args to customize behavior and configuration
          # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
          # or https://code.claude.com/docs/en/cli-reference for available options
          # claude_args: '--allowed-tools Bash(gh pr:*)'
  1. Open a pull request in the repository.
  2. Allow the workflow to run in agent mode.
  3. Observe the logs.

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.49

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

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