Skip to content
LatchkeyLatchkey home

GitHub Actions concurrency in a reusable workflow cancels the wrong run in CI

A concurrency group defined inside a reusable workflow is shared across every caller that uses it. If the group key is static, one caller's run cancels another's. Scope the key with caller context so groups stay independent.

What this error means

Runs from different branches or callers cancel each other unexpectedly, because the reusable workflow uses a fixed concurrency group name shared by all invocations.

GitHub Actions
Canceling since a higher priority waiting request for
'deploy-group' exists
# a static concurrency group inside deploy.yml is shared by all callers

Diagnose it: what token do you actually have?

Permission failures in Actions are almost never about your repository settings alone. Three things combine: the default GITHUB_TOKEN permission set for the repo or organization, the permissions: block in the workflow, and whether the event is a fork pull request, which downgrades the token to read-only regardless of everything else.

.github/workflows/ci.yml
- name: Show the token scopes actually granted
  run: |
    curl -sI -H "Authorization: Bearer $GITHUB_TOKEN" \
      https://api.github.com/ | grep -i "^x-oauth-scopes\|^x-accepted"
    echo "event: ${{ github.event_name }}"
    echo "fork PR: ${{ github.event.pull_request.head.repo.fork }}"
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Common causes

A static concurrency group in the callee

The reusable workflow sets concurrency: deploy-group with no per-caller context, so all callers land in one group and cancel each other.

No caller context in the group key

Without github.ref, github.workflow, or an input in the key, distinct runs are treated as the same concurrency group.

How to fix it

Scope the concurrency group with context

  1. Include a caller-specific value (github.ref, an input) in the group key.
  2. Keep the group unique per environment or branch.
  3. Re-run so independent callers no longer cancel each other.
.github/workflows/deploy.yml
# deploy.yml
concurrency:
  group: deploy-${{ inputs.environment }}-${{ github.ref }}
  cancel-in-progress: true

Set concurrency in the caller instead

If the group should be per-caller, define concurrency in the calling workflow where the full caller context is available.

.github/workflows/ci.yml
# ci.yml
concurrency:
  group: ci-${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

Grant the narrowest permission that works

Declaring a permissions: block switches the job from the repository default to exactly what you list, so an incomplete block is a common cause of a new failure right after someone tightened security. List every scope the job needs, not just the one that failed.

.github/workflows/ci.yml
permissions:
  contents: read        # checkout
  packages: write       # push to GHCR
  id-token: write       # OIDC to a cloud provider
  pull-requests: write  # comment on or label a PR
  checks: write         # publish check runs

How to prevent it

  • Include caller context in any concurrency group used by shared workflows.
  • Decide deliberately whether concurrency belongs in the caller or callee.
  • Test with two branches to confirm groups do not collide.

Frequently asked questions

What causes GitHub Actions concurrency in a reusable workflow cancels the wrong run in CI?
There are 2 common causes: a static concurrency group in the callee and no caller context in the group key. The reusable workflow sets concurrency: deploy-group with no per-caller context, so all callers land in one group and cancel each other.
How do I fix GitHub Actions concurrency in a reusable workflow cancels the wrong run in CI?
There are 2 fixes depending on which cause you have: scope the concurrency group with context and set concurrency in the caller instead. Work through them in order, since the first is the most common.
What does GitHub Actions concurrency in a reusable workflow cancels the wrong run in CI actually mean?
Runs from different branches or callers cancel each other unexpectedly, because the reusable workflow uses a fixed concurrency group name shared by all invocations.
How do I stop GitHub Actions concurrency in a reusable workflow cancels the wrong run in CI happening again?
Include caller context in any concurrency group used by shared workflows. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card