Skip to content
Latchkey

GitLab CI "rules:changes" Not Matching - Job Always or Never Runs

rules:changes runs a job only when matching files changed. It misfires when the glob is wrong, when there is no comparison base, or when the pipeline source has no diff to evaluate.

What this error means

A job guarded by rules:changes runs on every pipeline (even when its files did not change) or never runs (even when they did). The path glob and the compare base are the usual culprits.

Job rules
# Expected to run only when src/ changed, but it runs every push:
build:
  rules:
    - changes:
        - src/*        # only top-level of src/, misses src/app/main.ts

Common causes

Glob does not match nested paths

src/* matches only the immediate children of src/. To match any depth you need src/**/*. A too-narrow glob makes the rule never match real changes.

No comparison base on branch pipelines

On a branch pipeline, changes compares against the previous commit. On the first pipeline for a new branch, or a pipeline with no diff, GitLab treats everything as changed, so the job always runs.

Wrong pipeline source for changes

For reliable MR diffs, the job should run in a merge request pipeline. In a plain branch pipeline the compare base is the prior commit, which can differ from the MR diff you intended.

How to fix it

Use recursive globs and an MR source

Match nested paths and evaluate changes against the MR target for predictable diffs.

.gitlab-ci.yml
build:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      changes:
        - src/**/*
        - package-lock.json

Set a compare target for branch pipelines

Pin what changes compares against so the first-pipeline "everything changed" behavior is controlled.

.gitlab-ci.yml
build:
  rules:
    - changes:
        paths:
          - src/**/*
        compare_to: 'refs/heads/main'

How to prevent it

  • Prefer src/**/* recursive globs over single-level src/*.
  • Evaluate changes in merge request pipelines for stable diffs.
  • Use compare_to to control the base on branch pipelines.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →