Skip to content
Latchkey

Nx affected "--base" / "--head" Mismatch - Fix in CI

nx affected diffs --base against --head to pick which projects changed. When the range is inverted, points at the wrong branch, or assumes a default base, CI either rebuilds everything or skips projects it should have tested.

What this error means

On a PR nx affected runs far too many projects (full rebuild) or far too few (skips real changes). It is deterministic for a given base/head pair - flip the pair and the selection flips with it.

Nx output
> nx affected -t test --base=HEAD --head=origin/main
 NX   Affected criteria defaulted to --base=HEAD --head=origin/main

# selected 0 projects on a branch that clearly changed code

Diagnose it: task graph and workspace resolution

Terminal
npx turbo run build --dry-run=json | head -40
npx nx graph --file=graph.json
pnpm -r list --depth -1 2>/dev/null || yarn workspaces list

Common causes

Base and head are inverted

Passing --base=HEAD --head=origin/main diffs the wrong direction. The base must be the older commit (the merge target) and head the tip of your branch.

Wrong default base for the branch

affected.defaultBase in nx.json (or the implied main) may not match the branch a PR actually targets, so the computed diff covers the wrong range.

A SHA that moved or is not fetched

An env-provided SHA that was force-pushed over, or a base ref that was never fetched, resolves to an unexpected commit and skews the affected set.

How to fix it

Order the range base→head correctly

Base is the comparison target (older); head is your branch tip. Let the official action derive both for pushes and PRs.

.github/workflows/ci.yml
- uses: nrwl/nx-set-shas@v4
- run: nx affected -t test --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }}

Set the right default base

Pin the merge-target branch so local nx affected (without flags) matches CI.

nx.json
{
  "affected": { "defaultBase": "origin/main" }
}

Verify the selection before running

Print the affected projects for the exact range so you can confirm it is sane.

Terminal
nx show projects --affected --base=origin/main --head=HEAD

How to prevent it

  • Use nrwl/nx-set-shas so base/head are correct for both pushes and PRs.
  • Keep affected.defaultBase aligned with your real merge target.
  • Print nx show projects --affected in CI to audit the selection.

Frequently asked questions

What causes Nx affected "--base" / "--head" mismatch?
There are 3 common causes: base and head are inverted, wrong default base for the branch, and a sha that moved or is not fetched. Passing --base=HEAD --head=origin/main diffs the wrong direction.
How do I fix Nx affected "--base" / "--head" mismatch?
There are 3 fixes depending on which cause you have: order the range base→head correctly, set the right default base, and verify the selection before running. Work through them in order, since the first is the most common.
What does Nx affected "--base" / "--head" mismatch actually mean?
On a PR nx affected runs far too many projects (full rebuild) or far too few (skips real changes).
How do I stop Nx affected "--base" / "--head" mismatch happening again?
Use nrwl/nx-set-shas so base/head are correct for both pushes and PRs. 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