{"record":{"id":"725bbc728c9b7237","repo":"remix-run/react-router","slug":"file-watcher-error-message","errorCode":null,"errorMessage":"File watcher error: ${message}","messagePattern":"File watcher error: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/react-router-dev/config/config.ts","lineNumber":885,"sourceCode":"    getConfig,\n    onChange: (handler: ChangeHandler) => {\n      if (!watch) {\n        throw new Error(\n          \"onChange is not supported when watch mode is disabled\",\n        );\n      }\n\n      changeHandlers.push(handler);\n\n      if (!fsWatcher) {\n        fsWatcher = chokidar.watch([root, appDirectory], {\n          ignoreInitial: true,\n          ignored: (path) => isIgnoredByWatcher(path, { root, appDirectory }),\n        });\n\n        fsWatcher.on(\"error\", (error: unknown) => {\n          let message = error instanceof Error ? error.message : String(error);\n          console.warn(colors.yellow(`File watcher error: ${message}`));\n        });\n\n        fsWatcher.on(\"all\", async (...args) => {\n          let [event, rawFilepath] = args;\n          let filepath = Path.normalize(rawFilepath);\n\n          let fileAddedOrRemoved = event === \"add\" || event === \"unlink\";\n\n          let appFileAddedOrRemoved =\n            fileAddedOrRemoved &&\n            filepath.startsWith(Path.normalize(appDirectory));\n\n          let rootRelativeFilepath = Path.relative(root, filepath);\n\n          let configFileAddedOrRemoved =\n            fileAddedOrRemoved &&\n            isEntryFile(\"react-router.config\", rootRelativeFilepath);\n","sourceCodeStart":867,"sourceCodeEnd":903,"githubUrl":"https://github.com/remix-run/react-router/blob/6beaca39526d5716c3c112ebb0782765baa5a9ce/packages/react-router-dev/config/config.ts#L867-L903","documentation":"In watch mode (`react-router dev`, or config watch subscribers), React Router watches the project root and app directory with chokidar. When the watcher emits an `error` event, the message is logged as a yellow `File watcher error: <message>` warning and watching continues in a degraded state — change-triggered restarts/rebuilds may silently stop firing until the watcher recovers or the process restarts. It never crashes the process by itself.","triggerScenarios":"chokidar emits `error` during dev: ENOSPC when the OS inotify user-watches limit is exhausted (deep node_modules/project trees), EACCES/EPERM on a watched path, unsupported filesystems (NFS, some Docker volume mounts on macOS), or the watch handle being closed externally.","commonSituations":"Large monorepos on Linux with default fs.inotify.max_user_watches; dev containers and CI dockers with tight inotify limits; projects on network file systems; many simultaneous dev servers/watchers on one host.","solutions":["Raise the OS watcher limits and restart: `sudo sysctl fs.inotify.max_user_watches=524288 fs.inotify.max_user_instances=1024` (persist in /etc/sysctl.conf); in Docker, set the same sysctls or run with enough inotify capacity","Restart `react-router dev` — the watcher is created lazily and a fresh process rebuilds it","Reduce the watched surface: keep the app under a leaner root; node_modules and ignored paths are already excluded by isIgnoredByWatcher, but huge unignored directories still cost watch handles","Read the exact <message> in the warning: EACCES points at permissions on a specific path, ENOSPC at limits — fix that path/limit accordingly"],"exampleFix":"# before (defaults, ENOSPC errors in dev)\nfs.inotify.max_user_watches=8192\n\n# after (/etc/sysctl.conf, then: sudo sysctl --system)\nfs.inotify.max_user_watches=524288\nfs.inotify.max_user_instances=1024","handlingStrategy":"validation","validationCode":"// pre-flight check before starting dev on Linux\nimport fs from \"node:fs\";\nfunction checkInotifyBudget(needed = 100000) {\n  if (process.platform !== \"linux\") return;\n  let watches = Number(fs.readFileSync(\"/proc/sys/fs/inotify/max_user_watches\", \"utf8\"));\n  if (watches < needed) {\n    throw new Error(`fs.inotify.max_user_watches=${watches} < ${needed}. Run: sudo sysctl fs.inotify.max_user_watches=${needed}`);\n  }\n}\ncheckInotifyBudget();","typeGuard":null,"tryCatchPattern":"// the library already swallows the chokidar error event and logs it;\n// wrap your own watcher usage (if any) the same way:\nwatcher.on(\"error\", (err) => { log.warn(`watcher: ${err.message}`); scheduleWatcherRestart(); });","preventionTips":["Raise fs.inotify.max_user_watches/max_user_instances on dev machines, Docker hosts, and CI images","Avoid running projects from NFS/network mounts; use a local clone for dev","If dev stops rebuilding after this warning, restart `react-router dev` rather than trusting the degraded watcher"],"tags":["dev-server","chokidar","inotify","filesystem","watch-mode"],"backgroundTag":"inotify-watch-limit","analyzedSha":"6beaca39526d5716c3c112ebb0782765baa5a9ce","analyzedAt":"2026-08-18T18:04:14.938Z","contentChangedAt":"2026-08-18T18:04:14.938Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}