PHP OPcache Serving Stale Code in CI - Clear or Disable for CLI
OPcache stores compiled PHP bytecode for speed. When opcache.validate_timestamps is off (or a process is long-lived), PHP keeps running the cached version of a file even after you change it - so CI executes stale code and a "fixed" test still fails.
What this error means
A code change does not take effect in CI: the old behaviour persists, tests that should pass still fail (or vice versa), and clearing the cache or disabling OPcache makes the new code run. Common with opcache.enable_cli=1 plus disabled timestamp validation.
# opcache.ini
opcache.enable_cli=1
opcache.validate_timestamps=0 # never re-checks files
# CI runs the OLD compiled version of UserService.php even after editing it,
# so the assertion you just fixed still reports the previous result.Common causes
Timestamp validation disabled
opcache.validate_timestamps=0 is a production optimisation - PHP never re-reads changed files. In CI that means edits within a run are ignored until the cache is cleared.
OPcache enabled for CLI with a shared cache
opcache.enable_cli=1 plus a persisted cache directory across CI steps can serve bytecode compiled from a previous checkout or step.
How to fix it
Enable timestamp validation in CI
Let OPcache re-check files so edits are picked up.
php -d opcache.validate_timestamps=1 -d opcache.revalidate_freq=0 bin/run.phpDisable OPcache for CLI in CI
For correctness over speed, turn off CLI OPcache during tests.
php -d opcache.enable_cli=0 vendor/bin/phpunitClear the cache between steps
- Call
opcache_reset()at the start of a long-lived worker. - Avoid persisting the OPcache directory across CI steps.
- Confirm with
php -i | grep opcachewhich settings are active.
How to prevent it
- Keep
opcache.validate_timestamps=1(or OPcache off) in CI; reserve0for production. - Do not persist the OPcache directory between CI steps.
- Reset OPcache at the start of long-lived workers.