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

  1. Create the file under tests/Fixtures mirroring the path in the message (the message shows the exact resolved location).
  2. Fix casing or path segments to match the filesystem exactly on Linux CI.
  3. 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.
  4. 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

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


AI-assisted analysis of pestphp/pest@1af74a215c (2026-08-21). Data as JSON: /api/errors/033aeea23995fefb. Report an issue: GitHub.