jest "ENOENT: no such file or directory" for a snapshot file in CI: case-sensitivity issue
Fixes the jest ENOENT error on a snapshot file that appears only in CI and is caused by filename case mismatch. Shows how to compare the import path casing against the committed filename with git ls-files, rename with git mv, and confirm the fix. Use when jest cannot find a snapshot or module file in CI that resolves fine locally. Not for genuinely missing files, snapshot value mismatches, or permission errors.
TL;DR
Your local filesystem is case-insensitive, so import Button from './button' resolves even when the file is really Button.js. CI runners use case-sensitive filesystems, so the same import fails with ENOENT. Find the casing mismatch with git ls-files, fix it with git mv (or fix the import), and the CI error goes away. One rename, no code changes.
jest "ENOENT: no such file or directory" for a snapshot file in CI: case-sensitivity issueSteps
- Copy the exact path from the CI ENOENT message and run
git ls-files | grep -i [the-filename]locally. Expected: you see the committed casing, which differs from what the import or the snapshot lookup asked for. - Check the import or the snapshot path in the spec for the wrong casing, for example an import of
./buttonwhen the file isButton.js, or a__snapshots__directory cased differently from the spec file name. Expected: you find the single mismatched segment. - Rename with git so the casing change is tracked:
git mv OldName.js newname.js(use a temp name in between on case-insensitive systems if git complains the names are identical). Expected:git statusshows the rename. - Commit and push, then rerun CI. Expected: the ENOENT error is gone and the snapshot file resolves.
Use this when
- Jest reports ENOENT for a snapshot or module file only in CI
- The file exists locally and the suite passes on a Mac or Windows machine
- A recent rename touched the file or the directory casing
Not for this skill when
- The file is genuinely missing (never committed, gitignored)
- The error is a snapshot VALUE mismatch, not a missing file
- The failure is a permissions error or a broken symlink
Variant phrasings
- jest snapshot file not found in CI but exists locally
- ENOENT snapshot snapshots case sensitive filesystem
- jest passes on Mac fails on Linux file not found
Why it happens
macOS and Windows default to case-insensitive filesystems: ./button and ./Button hit the same file. Linux CI runners are case-sensitive, so the wrong casing is a genuinely different path and the lookup fails. Renames done through a GUI or an editor often change content but leave git holding the old casing, which is why the bug survives local runs.
Edge cases
- The mismatch can hide in the directory name (
__Snapshots__vs__snapshots__), not just the file. Check every segment. - If two files differ only by case, the repo is broken on case-insensitive checkouts too. Rename one of them properly.
- After the rename, search the codebase for other imports using the old casing so the next CI run does not hit the same bug in a different spec.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_LSAAXh2FE4dsezMfzlpSpQ