pestphp/pest · error · InvalidArgumentException
The fixture file [$file] does not exist.
Error message
The fixture file [$file] does not exist.
What it means
The fixture() helper resolves a path as rootPath/testPath/Fixtures/<file> (slashes normalized per platform) and returns its realpath. If realpath() returns false — file or an ancestor directory missing — Pest throws InvalidArgumentException with the full resolved path. Note the base is always tests/Fixtures; paths outside it cannot be reached with fixture().
Source
Thrown at src/Functions.php:241
$configurationRepository->globalConfiguration('default')->class(...$targets); // @phpstan-ignore-line
}
}
}
if (! function_exists('fixture')) {
function fixture(string $file): string
{
$file = implode(DIRECTORY_SEPARATOR, [
TestSuite::getInstance()->rootPath,
TestSuite::getInstance()->testPath,
'Fixtures',
str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $file),
]);
$fileRealPath = realpath($file);
if ($fileRealPath === false) {
throw new InvalidArgumentException(
'The fixture file ['.$file.'] does not exist.',
);
}
return $fileRealPath;
}
}
if (! function_exists('visit')) {
/**
* @template TUrl of array<int, string>|string
*
* @param TUrl $url
* @param array<string, mixed> $options
* @return (TUrl is array<int, string> ? ArrayablePendingAwaitablePage : PendingAwaitablePage)
*/
function visit(array|string $url, array $options = []): ArrayablePendingAwaitablePage|PendingAwaitablePage
{View on GitHub (pinned to 1af74a215c)
Solutions
- Create the file under tests/Fixtures mirroring the path in the message (the message shows the exact resolved location).
- Fix casing or path segments to match the filesystem exactly on Linux CI.
- If the file lives elsewhere in the repo, reference it directly (e.g., dirname(__DIR__).'/stubs/x.json') instead of fixture(), which is rooted at tests/Fixtures.
- Verify large/binary fixtures are committed (git lfs track) so fresh clones and CI get them.
Example fix
// before
it('parses config', function () {
$path = fixture('config.yml'); // tests/Fixtures/config.yml missing
});
// after: create tests/Fixtures/config.yml, or point at the real location
it('parses config', function () {
$path = fixture('config.yml');
});
// mkdir -p tests/Fixtures && printf 'key: value\n' > tests/Fixtures/config.yml Defensive patterns
Strategy: validation
Validate before calling
$relative = 'invoices/sample.json';
$base = implode(DIRECTORY_SEPARATOR, [getcwd(), 'tests', 'Fixtures', ...explode('/', $relative)]);
if (! file_exists($base)) {
throw new RuntimeException("Fixture missing: {$base}");
}
$path = fixture($relative); Prevention
- Commit every file referenced by fixture(); track large/binary fixtures with git lfs and verify fresh clones.
- Keep fixture paths lowercase and consistent to avoid casing failures on Linux CI.
- Run a meta-test that asserts all fixtures referenced in the suite exist.
When it happens
Trigger: fixture('invoices/sample.json') when tests/Fixtures/invoices/sample.json does not exist; wrong casing on case-sensitive filesystems (Fixture.json vs fixture.json); passing an absolute path or one that escapes Fixtures via ../..; forgetting that the .snapshot/.json file was never committed.
Common situations: Git checkouts missing binary/large fixtures excluded by .gitignore or LFS misconfiguration; renaming fixture folders without updating tests; parallel CI on Linux catching casing errors that macOS/Windows masked; teammates assuming fixture() reads arbitrary project files.
Related errors
- The test directory [%s] does not exist.
- Cached failure
- The test expects [%d] argument(s), but the dataset only prov
- Expectation value is not iterable.
- No sequence expectations defined.
AI-assisted analysis of pestphp/pest@1af74a215c (2026-08-21).
Data as JSON: /api/errors/033aeea23995fefb.
Report an issue: GitHub.