sebastianbergmann/phpunit · error · FileDoesNotHaveLineException
File "%s" does not have line %d
Error message
File "%s" does not have line %d
What it means
To hash a baseline issue, PHPUnit reads the file and takes the sha1 of line N (FILE_IGNORE_NEW_LINES, zero-based index line-1). The file exists but has fewer lines than requested, so FileDoesNotHaveLineException reports the file and line. Like error 111, this only happens when the hash is computed — Issue::from() with null hash, i.e. during --generate-baseline or when the ErrorHandler re-hashes a freshly triggered issue to compare it against a loaded baseline.
Source
Thrown at src/Runner/Baseline/Issue.php:138
* @param positive-int $line
*
* @throws FileDoesNotExistException
* @throws FileDoesNotHaveLineException
*
* @return non-empty-string
*/
private static function calculateHash(string $file, int $line): string
{
$lines = @file($file, FILE_IGNORE_NEW_LINES);
if ($lines === false && !is_file($file)) {
throw new FileDoesNotExistException($file);
}
$key = $line - 1;
if (!isset($lines[$key])) {
throw new FileDoesNotHaveLineException($file, $line);
}
$hash = sha1($lines[$key]);
assert($hash !== '');
return $hash;
}
}
View on GitHub (pinned to f123cdb2a2)
Solutions
- Regenerate the baseline after source changes: vendor/bin/phpunit --generate-baseline=<path>.
- If only some entries are stale, delete the baseline file (or offending entries) and regenerate.
- When integrating Issue programmatically, supply the hash explicitly so no line lookup happens.
Example fix
# before: stale baseline after editing sources vendor/bin/phpunit --baseline=.phpunit/baseline.xml # after: regenerate, then run vendor/bin/phpunit --generate-baseline=.phpunit/baseline.xml vendor/bin/phpunit --baseline=.phpunit/baseline.xml
Defensive patterns
Strategy: validation
Validate before calling
// Before hashing line N of a file
$lines = file($file, FILE_IGNORE_NEW_LINES);
if ($lines === false || count($lines) < $line) {
// file shrank or line moved: skip or regenerate the baseline
return;
} Prevention
- Regenerate the baseline after any source edit that adds or removes lines.
- Keep baselines short-lived; regenerate in CI rather than committing long-lived files across refactors.
- When integrating Issue programmatically, supply the hash explicitly so no line lookup happens.
When it happens
Trigger: A baseline was generated against an older revision; the file has since been edited (lines removed), and on the next run the recorded line number is beyond EOF when re-hashed. Also: generating a baseline for dynamically generated code whose line numbers exceed the on-disk file.
Common situations: Editing source between --generate-baseline and the next --baseline run; rebases and line shifts; PHAR or generated-code paths with synthetic line numbers.
Related errors
- File "%s" does not exist
- Cannot read baseline %s, file does not exist
- Cannot read baseline %s: %s
- Cannot read baseline %s, version %d is not supported
- Cannot write baseline to "%s".
AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23).
Data as JSON: /api/errors/7f2ac8ebc0ae5298.
Report an issue: GitHub.