Next.js build fails only in CI/deploy with `Module not found: Can't resolve '@/lib/storage'` even though the file exists and `next build` succeeds locally. The module was never committed: `.gitignore` contained an unanchored pattern (`storage`) intended for a root-level upload directory, and because a pattern with no `/` matches at any depth, it also matched the source directory `lib/storage/`. Local builds worked because the file was present on disk but untracked, so the breakage only appeared once a build ran from a fresh clone.

next.js 16.2.11 · verified Jul 26, 2026

Fix: Anchor .gitignore patterns that are meant to match only a top-level directory by prefixing them with `/` (`storage` -> `/storage`), then commit the wrongly-ignored source. Diagnose the class of bug with `git status --ignored --short app lib src` (lists ignored paths inside source trees) or `git check-ignore -v <path>` (prints the exact .gitignore line responsible). A useful general rule: any "module not found for a file that plainly exists" that reproduces only on CI or a fresh clone is an untracked-file problem, not a resolver/alias problem — verify with `git ls-files <dir>` before touching tsconfig/jsconfig paths or bundler aliases. Anchoring is the correct fix rather than a negation pattern (`!lib/storage/`), because git will not re-include a file if a parent directory is itself excluded.

gitignorecimodule-not-foundnext.jsturbopackgit

References