{"record":{"id":"552d3d8d590c7f10","repo":"jdx/mise","slug":"cannot-watch-the-system-s-watch-limit-is-reach","errorCode":null,"errorMessage":"cannot watch {}: the system's watch limit is reached (on Linux raise fs.inotify.max_user_watches)","messagePattern":"cannot watch (.+?): the system's watch limit is reached \\(on Linux raise fs\\.inotify\\.max_user_watches\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/watch/runtime.rs","lineNumber":1408,"sourceCode":"        if wanted.contains(anchor) {\n            current.push(anchor.clone());\n        } else if let Err(err) = debouncer.unwatch(&anchor.path) {\n            debug!(\"history watch: unwatch {}: {err}\", anchor.path.display());\n        }\n    }\n    for anchor in wanted {\n        if current.contains(anchor) {\n            continue;\n        }\n        let mode = match anchor.mode {\n            Mode::Recursive => RecursiveMode::Recursive,\n            Mode::Flat => RecursiveMode::NonRecursive,\n        };\n        match debouncer.watch(&anchor.path, mode) {\n            Ok(()) => current.push(anchor.clone()),\n            Err(err) if matches!(err.kind, notify::ErrorKind::MaxFilesWatch) => {\n                if current.is_empty() {\n                    bail!(\n                        \"cannot watch {}: the system's watch limit is reached (on Linux raise fs.inotify.max_user_watches)\",\n                        display_path(&anchor.path)\n                    );\n                }\n                let message = format!(\n                    \"cannot watch {}: the system's watch limit is reached; reconciliation still saves it (on Linux raise fs.inotify.max_user_watches)\",\n                    display_path(&anchor.path)\n                );\n                capture.health.watcher.degraded.push(message.clone());\n                capture.out.emit(\n                    \"degraded\",\n                    &message,\n                    json!({ \"path\": display_path(&anchor.path) }),\n                );\n            }\n            Err(err) => {\n                let message = format!(\n                    \"cannot watch {}: {err}; reconciliation still saves it\",","sourceCodeStart":1390,"sourceCodeEnd":1426,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/watch/runtime.rs#L1390-L1426","documentation":"When installing watches for tracked roots, the notify debouncer failed with ErrorKind::MaxFilesWatch and there was no fallback anchor already installed, so the runtime cannot receive change events for the path at all and aborts. The kernel's per-user watch limit (inotify watches on Linux) is exhausted.","triggerScenarios":"Calling run/reinstall when the tracked set requires a new recursive watch on a large tree while the process has hit inotify.max_user_watches (Linux) or the equivalent OS limit; typical when tracking a directory with tens of thousands of files.","commonSituations":"Linux systems with small fs.inotify.max_user_watches (default 8192) and large node_modules-style trees; containers with low limits; many dev tools (VS Code, webpack) consuming watches simultaneously.","solutions":["Raise the Linux watch limit: `sudo sysctl fs.inotify.max_user_watches=524288` and persist it in /etc/sysctl.conf or /etc/sysctl.d/.","Reduce the tracked set — untrack very large directories so fewer recursive watches are needed.","Check current consumption with `sysctl fs.inotify.max_user_watches` and `find ~/ tracked-dir | wc -l`; free watches by closing other watchers (editors, file sync tools).","In containers, raise the limit on the host or run with a higher sysctl (e.g. docker run --sysctl fs.inotify.max_user_watches=524288)."],"exampleFix":"// before (default limit too small)\n$ cat /proc/sys/fs/inotify/max_user_watches\n8192\n// after\n$ echo 'fs.inotify.max_user_watches=524288' | sudo tee /etc/sysctl.d/60-inotify.conf\n$ sudo sysctl --system","handlingStrategy":"fallback","validationCode":"# check watch headroom before installing watches\nsysctl fs.inotify.max_user_watches\nfind <tracked-root> -type f | wc -l   # rough per-root watch demand","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"watch limit is reached\") => {\n        eprintln!(\"raise fs.inotify.max_user_watches or reduce tracked roots\");\n        // fall back to periodic reconciliation instead of watching\n    }\n    other => other?,\n}","preventionTips":["Raise fs.inotify.max_user_watches to 524288 on Linux dev machines","Avoid tracking huge vendored/node_modules trees","Close other heavy file watchers (editors, bundlers) when watch limits are tight","In containers, pass --sysctl fs.inotify.max_user_watches at startup"],"tags":["filesystem","inotify","file-watching","resource-limit"],"backgroundTag":"resource-not-found","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}