jestjs/jest · error · Error

jest-haste-map: enableSymlinks config option was set, but…

Error message

jest-haste-map: enableSymlinks config option was set, but is incompatible with watchman.
Set either `enableSymlinks` to false or `useWatchman` to false.

What it means

jest-haste-map cannot follow symlinks when using the watchman crawler backend, because watchman resolves real paths and would index files under incorrect paths. When both `enableSymlinks: true` and `useWatchman: true` (the default) are set, the constructor throws immediately to prevent silent mis-indexing. This is a hard incompatibility, not a performance warning.

Solutions

  1. Set `haste: { enableSymlinks: true }` AND pass `watchman: false` (e.g. `--watchman=false` CLI flag or `globalConfig.watchman = false`).
  2. If you do not actually need symlink following, leave `enableSymlinks` at its default false and keep watchman.
  3. In a custom HasteMap caller, pass `useWatchman: false` in the options object alongside `enableSymlinks: true`.

Example fix

// before
module.exports = {
  haste: { enableSymlinks: true },
  // watchman defaults to true → conflict
};
// after
module.exports = {
  haste: { enableSymlinks: true },
  // disable watchman so the node crawler (fdir) handles symlinks
};
// CLI: jest --watchman=false
Defensive patterns

Strategy: validation

Validate before calling

// Validate config compatibility before HasteMap.create.
function validateHasteOptions(opts: { enableSymlinks?: boolean; useWatchman?: boolean }) {
  if (opts.enableSymlinks && (opts.useWatchman ?? true)) {
    throw new Error(
      'enableSymlinks requires useWatchman:false — set watchman:false in config or CLI.'
    );
  }
}

Prevention

When it happens

Trigger: Setting `haste.enableSymlinks: true` in jest.config while leaving `useWatchman` at its default true. The guard at index.ts:262 checks `this._options.enableSymlinks && this._options.useWatchman` and throws.

Common situations: Monorepo setups (pnpm, Yarn workspaces with symlinks) that enable symlink support for correct module resolution but forget to disable watchman. Also when copying a config snippet that sets enableSymlinks without the companion useWatchman:false.

Related errors


AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10). Data as JSON: /api/errors/92a030744fd5adc3. Report an issue: GitHub.

Appendix: source

Thrown at packages/jest-haste-map/src/index.ts:263

    this._console = options.console || globalThis.console;

    if (options.ignorePattern) {
      if (options.ignorePattern instanceof RegExp) {
        this._options.ignorePattern = new RegExp(
          `${options.ignorePattern.source}|${VCS_DIRECTORIES}`,
          options.ignorePattern.flags,
        );
      } else {
        throw new TypeError(
          'jest-haste-map: the `ignorePattern` option must be a RegExp',
        );
      }
    } else {
      this._options.ignorePattern = new RegExp(VCS_DIRECTORIES);
    }

    if (this._options.enableSymlinks && this._options.useWatchman) {
      throw new Error(
        'jest-haste-map: enableSymlinks config option was set, but ' +
          'is incompatible with watchman.\n' +
          'Set either `enableSymlinks` to false or `useWatchman` to false.',
      );
    }

    this._ignoreFn = buildIgnoreMatcher(
      this._options.ignorePattern,
      this._options.retainAllFiles,
    );
    this._workerPool = new WorkerPool({
      maxWorkers: this._options.maxWorkers,
      workerPath: require.resolve('./worker'),
      workerThreads: this._options.workerThreads,
    });
    this._fileProcessor = new FileProcessor(
      {
        computeDependencies: this._options.computeDependencies,

View on GitHub (pinned to 8e6d128e4a)