Skip to content
Latchkey

GitHub Actions Job-Level vs Workflow-Level concurrency Scope Mismatch

Runs serialize or cancel more (or less) than intended because concurrency was set at the wrong level. A top-level concurrency governs the entire run; a job-level concurrency governs only that job.

What this error means

A whole workflow is queued or cancelled when you only meant to serialize one deploy job, or two jobs contend unexpectedly because the group was declared at the workflow level.

.github/workflows/ci.yml
concurrency: deploy       # workflow level - serializes the ENTIRE run
jobs:
  build: { runs-on: ubuntu-latest, steps: [{ run: make }] }
  deploy: { runs-on: ubuntu-latest, steps: [{ run: ./deploy.sh }] }

Common causes

Top-level group serializes everything

A workflow-level concurrency block puts the whole run in one group, so even unrelated jobs (build) contend with the one you meant to serialize (deploy).

Expecting job isolation from a workflow group

A workflow-level group cannot serialize just one job. Per-job control requires a concurrency block on that job.

How to fix it

Put concurrency on the job that needs it

Scope the group to the deploy job so build is unaffected.

.github/workflows/ci.yml
jobs:
  build: { runs-on: ubuntu-latest, steps: [{ run: make }] }
  deploy:
    concurrency:
      group: deploy-${{ github.ref }}
      cancel-in-progress: false
    runs-on: ubuntu-latest
    steps: [{ run: ./deploy.sh }]

Use workflow-level only for whole-run control

  1. Apply top-level concurrency when you want to supersede entire runs (e.g. fast CI).
  2. Apply job-level concurrency to serialize a single sensitive job like deploy.
  3. Key groups on the ref/environment so unrelated work does not contend.

How to prevent it

  • Decide whether you need whole-run or single-job serialization, then set the level accordingly.
  • Use job-level concurrency for deploys so CD does not block CI.
  • Key concurrency groups on ref or environment to avoid cross-contention.

Frequently asked questions

What causes "concurrency scope"?
A workflow-level concurrency block puts the whole run in one group, so even unrelated jobs (build) contend with the one you meant to serialize (deploy).
How do I fix concurrency scope?
Scope the group to the deploy job so build is unaffected.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card