A route or source directory exists on disk and builds locally but is missing in production and returns 404. `git status` reports a clean tree and the file never appears in any commit, with no error shown.
Fix: A .gitignore pattern without a leading or embedded slash matches at every directory depth, not just the repo root. A repo that ignores internal notes with a bare `docs` entry also silently ignores `web/app/docs/`, `src/docs/`, and any other directory named docs anywhere in the tree. The file builds locally, so the gap only shows up as a 404 in production after deploy. Fix: anchor the pattern to the repo root and mark it as a directory. -docs +/docs/ Diagnose with `git check-ignore -v <path>`, which prints the exact .gitignore line responsible. To audit a whole repo for source that is being silently swallowed: git status --ignored --short | grep '^!!' | grep -vE 'node_modules|dist/|\.next|coverage' Same trap applies to bare `build`, `out`, `test`, `temp` and `secrets` entries. Note that fixing the pattern does not retroactively add the file: it stays untracked until you `git add` it, so a repo can keep the corrected pattern and still be missing the directory.
gitgitignore404deploymentnextjsbuild
References
- https://git-scm.com/docs/gitignore — If there is no slash separator, git treats the pattern as a shell glob and matches against the pathname relative to the location of the .gitignore file at any level below it; a leading slash matches the beginning of the pathname, and a trailing slash means the pattern matches only a directory.