{"record":{"id":"fca864b6669f07a4","repo":"jestjs/jest","slug":"failed-to-start-watch-mode","errorCode":null,"errorMessage":"Failed to start watch mode.","messagePattern":"Failed to start watch mode\\.","errorType":"exception","errorClass":"AggregateError","httpStatus":null,"severity":"error","filePath":"packages/jest-haste-map/src/watchers/index.ts","lineNumber":82,"sourceCode":"  }\n\n  async start(onChange: OnChangeCallback): Promise<void> {\n    const Backend: WatcherCtor = this._useWatchman\n      ? WatchmanWatcher\n      : ParcelWatcher;\n\n    const results = await Promise.allSettled(\n      this._roots.map(root => this._createWatcher(Backend, root, onChange)),\n    );\n    const fulfilled = results\n      .filter(r => r.status === 'fulfilled')\n      .map(r => (r as PromiseFulfilledResult<IWatcher>).value);\n    const rejected = results\n      .filter(r => r.status === 'rejected')\n      .map(r => (r as PromiseRejectedResult).reason);\n    if (rejected.length > 0) {\n      await Promise.allSettled(fulfilled.map(w => w.close()));\n      throw new AggregateError(rejected, 'Failed to start watch mode.');\n    }\n    this._watchers = fulfilled;\n  }\n\n  async close(): Promise<void> {\n    await Promise.all(this._watchers.map(watcher => watcher.close()));\n    this._watchers = [];\n  }\n\n  private _createWatcher(\n    Backend: WatcherCtor,\n    root: string,\n    onChange: OnChangeCallback,\n  ): Promise<IWatcher> {\n    const watcher = new Backend(root, {\n      console: this._console,\n      dot: true,\n      glob: this._extensions.map(ext => `**/*.${ext}`),","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-haste-map/src/watchers/index.ts#L64-L100","documentation":"When jest-haste-map starts watch mode, it instantiates one watcher per root and waits for each to emit 'ready' within 240 seconds. If any watcher rejects (emits 'error' during startup) or times out without becoming ready, WatcherDriver.start throws an AggregateError whose message is 'Failed to start watch mode.' The AggregateError's `errors` array contains the per-root rejection reasons.","triggerScenarios":"WatcherDriver.start uses Promise.allSettled over _createWatcher calls (line 71). A watcher's 'error' event fires during startup (onStartupError rejects), or the 240s MAX_WAIT_TIME timeout fires (line 121-126) rejecting with this same message. When any root is rejected, all fulfilled watchers are closed and the AggregateError is thrown at line 82.","commonSituations":"A root directory does not exist or is not watchable; watchman subscription fails; @parcel/watcher native binding crashes or is missing on the platform; inotify watch limit exhausted on Linux (`fs.inotify.max_user_watches` too low); very large repos where 240s is insufficient for the initial crawl.","solutions":["Check the AggregateError's `errors` array for the per-root cause — `catch(e) { console.error(e.errors) }`.","Raise the Linux inotify limit: `echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p`.","Remove or fix any non-existent root directory from the Jest config.","Reinstall native deps (`npm rebuild`) if @parcel/watcher binding is missing.","If using watchman, run `watchman version` and `watchman shutdown-server`, then restart."],"exampleFix":"// before — root doesn't exist\nmodule.exports = { roots: ['<rootDir>/src', '<rootDir>/deleted-pkg'] };\n// after\nmodule.exports = { roots: ['<rootDir>/src'] };","handlingStrategy":"validation","validationCode":"// Verify roots and inotify limits before starting watch mode (Linux).\nimport { existsSync } from 'node:fs';\nimport { readFileSync } from 'node:fs';\nfunction checkWatchPrereqs(roots: string[]) {\n  const missing = roots.filter(r => !existsSync(r));\n  if (missing.length) throw new Error(`Unwatchable roots: ${missing.join(', ')}`);\n  if (process.platform === 'linux') {\n    const max = readFileSync('/proc/sys/fs/inotify/max_user_watches', 'utf8').trim();\n    if (Number(max) < 524288) {\n      console.warn(`inotify max_user_watches=${max} is low; consider raising it.`);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await watcherDriver.start(onChange);\n} catch (error) {\n  if (error instanceof AggregateError) {\n    for (const reason of error.errors) console.error('Root watcher failed:', reason);\n  }\n  throw error;\n}","preventionTips":["Validate every root exists before enabling watch mode.","On Linux, raise `fs.inotify.max_user_watches` to 524288+.","Ensure @parcel/watcher native bindings are installed (`npm rebuild`).","Restart stale watchman daemons with `watchman shutdown-server`."],"tags":["watch-mode","filesystem","watchman","parcel-watcher","inotify","configuration"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}