[BUG] /install-github-app generates claude-code-review.yml using a terminal CLI plugin in CI, causing silent failures

Resolved 💬 10 comments Opened Feb 17, 2026 by arjunven Closed May 3, 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?

Bug Description

/install-github-app generates a claude-code-review.yml workflow that uses the code-review plugin (code-review@claude-code-plugins). That plugin appears to be designed for interactive terminal use, not headless CI. The result is a workflow that runs, costs money, and silently produces no review.

This is related to #7710 (wrong permissions), but is a deeper issue: even with permissions fixed, the generated workflow appears to be architecturally wrong.

## Environment

  • Claude Code CLI Version: 2.1.44
  • Platform: macOS
  • Auth method: OIDC (claude_code_oauth_token)

## Stock Generated Workflows

### claude.yml (generated by /install-github-app)

```yaml
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
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 }}
additional_permissions: |
actions: read
```

### claude-code-review.yml (generated by /install-github-app)

```yaml
name: Claude Code Review

on:
pull_request:
types: [opened, synchronize, ready_for_review, reopened]

jobs:
claude-review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write

steps:

  • name: Checkout repository

uses: actions/checkout@v4
with:
fetch-depth: 1

  • name: Run Claude Code Review

id: claude-review
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
```

## Problems

### 1. claude-code-review.yml: The code-review plugin appears to be a terminal CLI plugin

Per the plugins README, code-review is a slash command plugin designed for interactive terminal use. It runs 5 parallel agents. It was never designed for a headless CI environment where it has no interactive session and must post results via the GitHub API.

### 2. claude-code-review.yml: pull-requests: read — cannot post reviews

The generated workflow uses pull-requests: read. Posting a review comment requires pull-requests: write. This means the plugin can never post a review regardless of anything else.

(This was also reported in #7710. The collaborator response was "use the Claude GitHub App instead of claude_code_oauth_token" — but the generated template explicitly uses claude_code_oauth_token, so that response doesn't address this template.)

### 3. claude-code-review.yml: No --allowedTools — Bash denied by default in SDK mode

In Claude Code SDK (non-interactive) mode, Bash is denied by default unless explicitly allowed. The plugin needs gh pr diff, gh api, etc. to fetch and post the review.
Without --allowedTools granting those, every useful call is denied. The plugin burns through turns and exits with success but no review posted.

### 4. claude.yml: pull-requests: read and issues: read — cannot post comments

The @claude interactive workflow also has read-only permissions. Claude responding to @claude mentions cannot post a comment back to the PR or issue.

## Observed Failure (claude-code-review.yml with OIDC auth, after manually fixing permissions to write)

Even after fixing permissions, the plugin still cannot function:

  • Run 1: 22 turns, $3.94 spent, every gh/grep/sed Bash call denied, no review posted
  • Run 2 (added --allowedTools "Bash(gh api*),Bash(gh pr*),Bash(git*)"): similar failures — compound && commands partially denied
  • Run 3 (removed --allowedTools entirely): success, $0.27, but still no review — gh api calls denied by SDK default Bash restriction

Meanwhile, using @claude in a PR comment to request a review (claude.yml flow) works correctly and produces a full review — because in that flow the action itself posts the response, Claude never needs to call gh api from Bash.

What Should Happen?

Expected Behaviour

/install-github-app should generate workflows that:

  1. Use pull-requests: write and issues: write for both generated workflows
  2. Replace the code-review plugin approach in claude-code-review.yml with a direct prompt: matching the official

pr-review-comprehensive.yml example

  1. Include correct --allowedTools for the review workflow (mcp__github_inline_comment__create_inline_comment, Bash(gh pr comment:*), Bash(gh pr diff:*), `Bash(gh pr

view:*)`)

  1. Work out of the box with OIDC auth (claude_code_oauth_token)

## Workaround

Replace the generated claude-code-review.yml with a workflow modelled on the official
pr-review-comprehensive.yml example, using a direct prompt instead of
the plugin.

Error Messages/Logs

Cache hit for: swrvKXH4hkDYFKcrNV+Kct676IY=
Received 4194304 of 35242129 (11.9%), 4.0 MBs/sec
Received 35242129 of 35242129 (100.0%), 26.4 MBs/sec
Cache Size: ~34 MB (35242129 B)
/usr/bin/tar -xf /home/runner/work/_temp/32562e71-bffe-4bb2-bcbb-b046042c1fbe/cache.tzst -P -C /home/runner/work/merlin/merlin --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.44
+ @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 [812.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: arjunven
Permission level retrieved: admin
Actor has write access: admin
Mode: agent
Context prompt: /code-review:code-review arjunven/merlin/pull/456
Trigger result: true
Preparing with mode: agent for event: pull_request
Actor type: User
Verified human actor: arjunven
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.44...
Installation attempt 1...
Setting up Claude Code...
^[[?2026h
Checkinginstallationstatus...
^[[?2026l^[[?2026h
Installing Clude Cde nive build2.1.44...
^[[?2026l^[[?2026h
Seting uplauncher and shellintegration. 
}
{
  "type": "system",
  "subtype": "init",
  "message": "Claude Code initialized",
  "model": "claude-sonnet-4-5-20250929"
}
{
  "type": "result",
  "subtype": "success",
  "is_error": false,
  "duration_ms": 43590,
  "num_turns": 10,
  "total_cost_usd": 0.2734538,
  "permission_denials": [
    {
      "tool_name": "Bash",
      "tool_use_id": "toolu_01Qojrdv6HFyjosQZeY2L4tU",
      "tool_input": {
        "command": "gh api repos/arjunven/merlin/pulls/456/comments 2>&1 | head -50 && gh api repos/arjunven/merlin/issues/456/comments 2>&1 | head -50",
        "description": "Get PR comments via API"
      }
    },
    {
      "tool_name": "Bash",
      "tool_use_id": "toolu_011i94KzH6GAqgPTaD9yhbpm",
      "tool_input": {
        "command": "gh api repos/arjunven/merlin/issues/456/comments 2>&1 | head -100",
        "description": "Get PR issue comments"
      }
    },
    {
      "tool_name": "Bash",
      "tool_use_id": "toolu_01BhHowxGXJP6sKMYGWS5Xjx",
      "tool_input": {
        "command": "gh api repos/arjunven/merlin/issues/456/comments",
        "description": "Get PR issue comments"
      }
    }
  ]
}
Log saved to /home/runner/work/_temp/claude-execution-output.json
Set session_id: 68f6a6b5-d9bf-47ea-879a-4ef9dc929ce1
Successfully formatted Claude Code report
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

Steps to Reproduce

  1. Run /install-github-app and follow the prompts
  2. Examine the generated .github/workflows/claude-code-review.yml

The generated file will have:

  • pull-requests: read (cannot post reviews)
  • issues: read (cannot post comments)
  • The code-review plugin — a terminal CLI plugin not designed for headless CI
  • No --allowedTools granting the Bash access the plugin needs in SDK non-interactive mode

Claude Model

None

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.44 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Other

Additional Information

_No response_

View original on GitHub ↗

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