{"record":{"id":"7f2ac8ebc0ae5298","repo":"sebastianbergmann/phpunit","slug":"file-s-does-not-have-line-d","errorCode":null,"errorMessage":"File \"%s\" does not have line %d","messagePattern":"File \"(.+?)\" does not have line (.+?)","errorType":"exception","errorClass":"FileDoesNotHaveLineException","httpStatus":null,"severity":"error","filePath":"src/Runner/Baseline/Issue.php","lineNumber":138,"sourceCode":"     * @param positive-int     $line\n     *\n     * @throws FileDoesNotExistException\n     * @throws FileDoesNotHaveLineException\n     *\n     * @return non-empty-string\n     */\n    private static function calculateHash(string $file, int $line): string\n    {\n        $lines = @file($file, FILE_IGNORE_NEW_LINES);\n\n        if ($lines === false && !is_file($file)) {\n            throw new FileDoesNotExistException($file);\n        }\n\n        $key = $line - 1;\n\n        if (!isset($lines[$key])) {\n            throw new FileDoesNotHaveLineException($file, $line);\n        }\n\n        $hash = sha1($lines[$key]);\n\n        assert($hash !== '');\n\n        return $hash;\n    }\n}\n","sourceCodeStart":120,"sourceCodeEnd":148,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Runner/Baseline/Issue.php#L120-L148","documentation":"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.","triggerScenarios":"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.","commonSituations":"Editing source between --generate-baseline and the next --baseline run; rebases and line shifts; PHAR or generated-code paths with synthetic line numbers.","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."],"exampleFix":"# before: stale baseline after editing sources\nvendor/bin/phpunit --baseline=.phpunit/baseline.xml\n\n# after: regenerate, then run\nvendor/bin/phpunit --generate-baseline=.phpunit/baseline.xml\nvendor/bin/phpunit --baseline=.phpunit/baseline.xml","handlingStrategy":"validation","validationCode":"// Before hashing line N of a file\n$lines = file($file, FILE_IGNORE_NEW_LINES);\nif ($lines === false || count($lines) < $line) {\n    // file shrank or line moved: skip or regenerate the baseline\n    return;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["phpunit","php","baseline","file-io"],"backgroundTag":"baseline-line-mismatch","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}