{"record":{"id":"85c7eec12f791c4d","repo":"jestjs/jest","slug":"haste-enablesymlinks-is-incompatible-with-watchman","errorCode":null,"errorMessage":"haste.enableSymlinks is incompatible with watchman","messagePattern":"haste\\.enableSymlinks is incompatible with watchman","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"packages/jest-config/src/normalize.ts","lineNumber":1062,"sourceCode":"            return {\n              config: watchPlugin[1] || {},\n              path: resolveWatchPlugin(newOptions.resolver, {\n                filePath: watchPlugin[0],\n                requireResolveFunction: requireResolve,\n                rootDir: options.rootDir,\n              }),\n            };\n          }\n        });\n        break;\n    }\n    // @ts-expect-error: automock is missing in GlobalConfig, so what\n    newOptions[key] = value;\n    return newOptions;\n  }, newOptions);\n\n  if (options.watchman && options.haste?.enableSymlinks) {\n    throw new ValidationError(\n      'Validation Error',\n      'haste.enableSymlinks is incompatible with watchman',\n      'Either set haste.enableSymlinks to false or do not use watchman',\n    );\n  }\n\n  for (const [i, root] of newOptions.roots.entries()) {\n    verifyDirectoryExists(root, `roots[${i}]`);\n  }\n\n  try {\n    // try to resolve windows short paths, ignoring errors (permission errors, mostly)\n    newOptions.cwd = tryRealpath(process.cwd());\n  } catch {\n    // ignored\n  }\n\n  newOptions.testSequencer = resolveSequencer(newOptions.resolver, {","sourceCodeStart":1044,"sourceCodeEnd":1080,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-config/src/normalize.ts#L1044-L1080","documentation":"normalize() (normalize.ts:1061-1067) rejects the combination of watchman-based file watching with haste.enableSymlinks. Watchman does not follow symlinks reliably, so following symlinks in the haste map while using watchman produces inconsistent module resolution. The ValidationError tells the user to pick one: disable symlinks or stop using watchman.","triggerScenarios":"Setting { watchman: true, haste: { enableSymlinks: true } } in jest.config; enabling enableSymlinks while watchman is the default crawler on the platform; CI that forces watchman=true alongside symlink support.","commonSituations":"Monorepos using symlinks (pnpm, yarn workspaces with links) where a user tried to enable symlink support without disabling watchman; copying a config snippet that set haste.enableSymlinks; defaulting watchman on macOS/Linux dev machines.","solutions":["Set haste.enableSymlinks to false (the default) if you need watchman.","Disable watchman: run jest --no-watchman or set watchman: false in config, if you need symlink following.","Switch to a non-watchman crawler (e.g. configure haste accordingly) when symlink support is required."],"exampleFix":"// before\nmodule.exports = {\n  watchman: true,\n  haste: { enableSymlinks: true },\n};\n// after (option A: keep watchman)\nmodule.exports = {\n  watchman: true,\n  haste: { enableSymlinks: false },\n};\n// after (option B: keep symlinks)\nmodule.exports = {\n  watchman: false,\n  haste: { enableSymlinks: true },\n};","handlingStrategy":"validation","validationCode":"function validateHasteWatchman(cfg: { watchman?: boolean; haste?: { enableSymlinks?: boolean } }): void {\n  if (cfg.watchman && cfg.haste?.enableSymlinks) {\n    throw new Error('haste.enableSymlinks is incompatible with watchman; pick one');\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default haste.enableSymlinks to false unless you specifically need symlink following.","If you need symlinks (pnpm-style), disable watchman (watchman: false).","Add a config-validation step in CI to catch incompatible option pairs."],"tags":["jest-config","haste","watchman","symlinks","validation"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}