A CI step fails when its command exits with a non zero code. A security gate is a scanner that returns non zero when findings cross your threshold. Everything else, from the red cross on a pull request to a blocked merge, follows from that one number.
The chain from scanner to merge button
- The scanner runs and decides pass or fail using your threshold.
- It exits with 0 for pass or a non zero code for fail.
- The CI job reports success or failure based on that code.
- CI posts a commit status or check to the pull request. A commit status has one of four states: error, failure, pending or success.
- Branch protection requires that check, so the merge button follows it.
A break at any link yields a gate that looks fine and blocks nothing.
What the code means in practice
The npm audit documentation is a good example. It exits 0 when no vulnerabilities are found, and by default exits non zero if any are found. With an audit level set, the exit code depends on that level, so a run can exit 0 even with findings below the level. The fix command exits 0 when no vulnerabilities remain after the fix.
Notice that the code is decided by the threshold, not by what was printed. People often read the report and assume the build will fail. It may not.
Mistakes that turn a failing scan green
| Mistake | Why it hides failure |
|---|---|
| Piping scanner output to another command | The shell reports the last command's code |
| Adding "or true" after the command | Forces exit 0 |
| Setting the job to continue on error | Job reports success despite failure |
| Wrapping in a script without propagating the code | The wrapper exits 0 |
| Treating a scanner crash as a pass | Errors and findings use different codes |
That last one deserves care. A scanner that cannot reach its database may exit with an error. Decide in advance whether an error blocks. Our post on what to do when the scanner is down covers the tradeoff.
Steps to verify your pipeline
- Run the scanner locally against a known vulnerable project and echo the exit code.
- Run the same command inside the CI job and compare.
- Search your pipeline files for continue on error and the pipe character near scan commands.
- Confirm the resulting check is marked required.
Keep the contract documented
Write a short note in the repository: which code means findings, which means tool error, and which action each triggers. When a new person edits the pipeline, they should not have to rediscover it.
Quick check
Does a scanner that prints findings always fail the build?
No. The exit code decides, and it depends on your threshold settings.
What should happen if the scanner itself errors?
Decide up front. Many teams block on error for protected branches and warn elsewhere.
Safeguard's CLI can run in a pipeline and report policy results, and its gates apply your rules to the outcome. Try the free scan at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.