Skip to content

claude-blocking-review.yml startup_failure on Dependabot PRs — secret contract blocks dispatch before the fast-pass can run #115

Description

@twistedmelonman

Observation

Claude Code Review (caller: claude-code-review.ymlclaude-blocking-review.yml@v3) fails with startup_failure and zero dispatched jobs on every Dependabot-authored PR, confirmed on smartwatermelon/repo-template PR #1 on both 2026-08-07 and 2026-08-11 (unrelated to the dependabot-auto-merge v2 migration work in progress on that PR — the failures predate it).

Root cause

claude-blocking-review.yml's workflow_call interface declares:

secrets:
  claude_oauth_token:
    required: true

The caller stub forwards it as secrets.CLAUDE_CODE_OAUTH_TOKEN. GitHub validates required-secret workflow_call contracts at dispatch time, before any job (or step inside a job) runs. Dependabot-triggered pull_request events run under a restricted token context that does not have access to repository secrets — so the secret the caller tries to forward resolves to nothing, GitHub can't satisfy the reusable workflow's required-secret contract, and the whole run fails to start: conclusion: startup_failure, jobs: [], billable: {}.

The reusable workflow already has a dependabot-check step (added per the "add dependabot fast-pass" commit, f723490) intended to skip AI review for Dependabot PRs cheaply. This fast-pass can never fire for this failure mode — it's a step inside the job, and the job never starts. The fast-pass only protects against wasted API spend on a running job; it does nothing for a startup_failure.

Impact

Every Dependabot PR across the fleet that uses claude-code-review.ymlclaude-blocking-review.yml gets a permanently red/failed check, even though the intent (per the existing fast-pass logic) was always to skip — not fail — AI review on these PRs. This is a false-negative CI signal fleet-wide, not specific to repo-template.

Suggested fix

Move the Dependabot skip decision to the caller (before the secret is ever referenced), e.g.:

jobs:
  claude-review:
    if: github.actor != 'dependabot[bot]'
    uses: smartwatermelon/github-workflows/.github/workflows/claude-blocking-review.yml@v3
    with:
      pr_number: ${{ github.event.pull_request.number }}
    secrets:
      claude_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

A caller-level if: prevents the reusable workflow from being invoked at all for Dependabot PRs, so the required-secret contract is never evaluated in a context where it can't be satisfied. This needs to land in the README's caller-stub example and in every consuming repo's claude-code-review.yml (or equivalent) — likely most/all of the same 31 repos touched by the dependabot-auto-merge v2 migration (dev-env#20), since they'd have copied the same caller-stub pattern.

The existing in-job dependabot-check fast-pass can stay as defense-in-depth for any trigger path that isn't gated by the caller-level if: (e.g. a repo-specific workflow that doesn't yet have it).

Discovered during

Canary testing the dependabot-auto-merge v2 migration on smartwatermelon/repo-template (dev-env#20) — unrelated to that work, but caught in the same investigation.

Claude-Session: https://claude.ai/code/session_01Q5QrbCLnJdAPjcCLu9UHNp

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions