Yes, path filters can start a scan workflow when files in one package change. The catch is that a skipped workflow leaves its checks in a Pending state, and a pull request that requires those checks cannot merge. Plan for that before you make a path filtered scan a required check.
How path filters behave
The GitHub Actions workflow syntax reference says that if at least one path matches a pattern in the paths filter, the workflow runs. With paths-ignore, the workflow does not run when all changed paths match the ignore patterns. You cannot use both for the same event in one workflow. You can use a leading exclamation mark inside paths to exclude, and order matters. Glob patterns use star and double star.
For pull requests, GitHub builds the changed file list with a three dot diff, which compares the latest topic branch version with the commit where it last synced with the base branch.
on:
pull_request:
paths:
- 'services/payments/**'
- 'libs/shared/**'
The pending check trap
GitHub states that if path filtering skips a workflow, its associated checks remain Pending, and a pull request that requires those checks to pass is blocked from merging. Then a docs only pull request cannot merge because the payments scan never ran.
You have three ways out.
| Approach | How it works | Trade off |
|---|---|---|
| Always run, decide inside | Trigger on every pull request, detect changes in a first job, skip later jobs | The check reports success when skipped |
| Aggregate check | One always running job that waits for conditional jobs | One extra job to maintain |
| Do not require the scan | Run it as advisory | Weaker control |
Detecting changes inside a workflow that always starts avoids the skipped workflow case. How a skipped job inside that workflow counts toward a required check depends on your settings, so test it on a throwaway pull request before you rely on it.
Shared code needs listing
A path filter for one package misses changes in the libraries it imports. If payments uses libs/shared, list both paths, or derive the affected set from your build graph. See scan only affected packages.
Lockfile changes are another case. A root lockfile change can affect many packages at once, so include the lockfile in every package filter or run everything when it changes.
Diff limits
The reference also describes limits. A push with more than 1,000 commits always runs the workflow. If generating the diff times out, the workflow always runs. If the diff has more than 3,000 files and the matches fall outside the first 3,000 returned, the workflow does not run. Large refactors can therefore behave oddly, so keep a scheduled full scan as a backstop.
A sound setup
- Run a full scan on a schedule, for example nightly.
- On pull requests, scan affected packages.
- Make one aggregate job the required check.
- Block on new high severity findings only.
Safeguard offers policies and gates that can stop a pull request on new findings. See the demo for how a gate behaves, and try the free scan at https://gold.safeguard.sh/scan.
Try it yourself
Click through the gate demo and notice what makes a pull request pass or fail.
Click through it at your own pace, or open it full screen.
Quick check
What happens to a required check when path filters skip the workflow?
It stays Pending and blocks the merge, according to GitHub documentation.
Why keep a scheduled full scan?
Path filters can miss changes in shared code, and diff limits can cause runs to be skipped or forced.
Sources
Last reviewed: 19 October 2026.