PHPStan / Psalm Failing CI - Static Analysis Errors Block the Build
PHPStan and Psalm fail CI on any reported issue above the configured level/threshold. A raised level, a new rule, an upgraded analyzer, or code that introduces a type problem turns the static-analysis step red - independent of whether the code runs.
What this error means
The PHPStan/Psalm step in CI exits non-zero, listing type errors (possibly null, undefined method, wrong argument type) or "baseline is outdated". Tests may pass; only static analysis fails.
$ vendor/bin/phpstan analyse --level=8 src
------ -------------------------------------------------------------------
Line src/OrderService.php
------ -------------------------------------------------------------------
42 Parameter #1 \$id of method Repo::find() expects int, string given.
------ -------------------------------------------------------------------
[ERROR] Found 1 errorCommon causes
New code introduces a type problem
A change adds a possibly-null access, a wrong argument type, or an undefined method that the analyzer flags at the configured level.
Level raised, analyzer upgraded, or baseline stale
Bumping the PHPStan level/Psalm errorLevel, upgrading the tool, or an out-of-date baseline surfaces issues that previously passed.
How to fix it
Fix the reported type issues
Address the findings at the source - narrow types, guard nulls, correct argument types.
// guard the null instead of passing it on
\$user = \$repo->find((int) \$id);
if (\$user === null) { throw new NotFoundException(); }Reproduce locally at the CI level
vendor/bin/phpstan analyse --level=8 src
vendor/bin/psalm --show-info=falseUpdate the baseline deliberately if needed
For a large legacy backlog, regenerate the baseline so new code is held to the standard while old debt is tracked.
vendor/bin/phpstan analyse --generate-baseline
# commit phpstan-baseline.neon; reduce it over timeHow to prevent it
- Run PHPStan/Psalm locally at the same level as CI before pushing.
- Treat static-analysis findings as build-blocking, not advisory.
- Keep baselines shrinking; do not hide genuine new errors in them.