{"record":{"id":"ceb47bab6565474b","repo":"sebastianbergmann/phpunit","slug":"cannot-read-from-s","errorCode":null,"errorMessage":"Cannot read from %s","messagePattern":"Cannot read from (.+?)","errorType":"validation","errorClass":"PHPUnit\\TextUI\\RuntimeException","httpStatus":null,"severity":"error","filePath":"src/TextUI/Configuration/TestSuiteBuilder.php","lineNumber":86,"sourceCode":"\n        if ($configuration->hasCliArguments() || $configuration->hasTestFilesFile()) {\n            $arguments = [];\n\n            if ($configuration->hasCliArguments()) {\n                foreach ($configuration->cliArguments() as $cliArgument) {\n                    $argument = realpath($cliArgument);\n\n                    if ($argument === false) {\n                        throw new TestFileNotFoundException($cliArgument);\n                    }\n\n                    $arguments[] = $argument;\n                }\n            }\n\n            if ($configuration->hasTestFilesFile()) {\n                if (!is_file($configuration->testFilesFile())) {\n                    throw new RuntimeException('Cannot read from ' . $configuration->testFilesFile());\n                }\n\n                $directory = dirname($configuration->testFilesFile()) . DIRECTORY_SEPARATOR;\n\n                $fileLines = file($configuration->testFilesFile());\n\n                // @codeCoverageIgnoreStart\n                if ($fileLines === false) {\n                    throw new RuntimeException('Cannot read from ' . $configuration->testFilesFile());\n                }\n                // @codeCoverageIgnoreEnd\n\n                foreach ($fileLines as $file) {\n                    $file     = trim($file);\n                    $argument = realpath($file);\n\n                    if ($argument === false) {\n                        $argument = realpath($directory . $file);","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/TextUI/Configuration/TestSuiteBuilder.php#L68-L104","documentation":"When --test-file-list is used, TestSuiteBuilder::build() first checks is_file() on the list file itself; if the path is not an existing regular file (missing, or a directory), it throws RuntimeException('Cannot read from ...'). The list file must be a plain text file containing one test file path per line.","triggerScenarios":"`vendor/bin/phpunit --test-file-list=tests/` (passing a directory instead of a file); a typo'd path; the list file was supposed to be generated by a previous pipeline step that failed silently; empty CI variable expanding to a bare or wrong path.","commonSituations":"Assuming the option accepts a directory; CI artifacts (the list) not uploaded between jobs; path relative to a different cwd.","solutions":["Point --test-file-list at an existing text file with one test path per line","Make the generating step fail loudly and verify the file exists before invoking phpunit: `test -s changed-tests.txt`","Use an absolute path in CI to avoid cwd surprises"],"exampleFix":"# before (directory passed by mistake)\nvendor/bin/phpunit --test-file-list=tests/\n\n# after\ngit diff --name-only main -- 'tests/*Test.php' > changed-tests.txt\nvendor/bin/phpunit --test-file-list=changed-tests.txt","handlingStrategy":"validation","validationCode":"$listFile = 'changed-tests.txt';\n\nif (!is_file($listFile) || !is_readable($listFile)) {\n    fwrite(STDERR, \"--test-file-list target missing or unreadable: {$listFile}\" . PHP_EOL);\n    exit(2);\n}\n\n// shell: test -s \"$list\" || { echo \"list generation failed\"; exit 2; }","typeGuard":null,"tryCatchPattern":"try {\n    (new \\PHPUnit\\TextUI\\Configuration\\TestSuiteBuilder)->build($configuration);\n} catch (\\RuntimeException $e) {\n    if (str_starts_with($e->getMessage(), 'Cannot read from ')) {\n        // the --test-file-list path is not a readable regular file; fix the path/generation step\n    }\n}","preventionTips":["--test-file-list takes a plain text file of paths, not a directory","Make the list-generation step fail loudly and assert the artifact exists before running tests","Use absolute paths in CI to eliminate cwd ambiguity"],"tags":["phpunit","cli","test-selection","test-file-list","file-not-found"],"backgroundTag":"unreadable-input-file","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}