jestjs/jest · error · Error

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

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

Symlink support (enableSymlinks) and watchman-backed crawling/watching (useWatchman) are mutually exclusive in jest-haste-map, because watchman's symlink semantics conflict with the resolveSymlinks:false mode the library requires. The constructor hard-fails at index.ts:262 if both are true so that haste-map never silently tracks files under the wrong path.

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 f49721c78e)

Solutions

  1. If you need symlink support, disable watchman: set Jest config `watchman: false` (and/or pass useWatchman:false to HasteMap).
  2. If you need watchman, disable symlinks: remove `haste.enableSymlinks` or set it to false.
  3. Prefer disabling watchman (option 1) when your repo relies on symlinked node_modules (pnpm/yarn workspaces), because enableSymlinks is required for correct module resolution there.

Example fix

// before — conflicting options
module.exports = {
  watchman: true,
  haste: { enableSymlinks: true },
};

// after — keep symlinks, drop watchman
module.exports = {
  watchman: false,
  haste: { enableSymlinks: true },
};
Defensive patterns

Strategy: validation

Validate before calling

if (options.enableSymlinks && options.useWatchman) {
  // hard-incompatible per jest-haste-map index.ts:262
  throw new Error('enableSymlinks and useWatchman are mutually exclusive; pick one.');
}

Prevention

When it happens

Trigger: Constructing HasteMap with both `enableSymlinks: true` and `useWatchman: true` (default). In Jest config this comes from `haste.enableSymlinks: true` combined with a caller (jest-core/jest-runtime) that passes `watchman: true`. The guard at index.ts:262 throws immediately during construction.

Common situations: Enabling symlinks to support pnpm/npm-linked workspaces or a monorepo with symlinked node_modules, while leaving watchman enabled (the default). Also seen after upgrading Jest where enableSymlinks became a supported haste key.

Related errors


AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03). Data as JSON: /data/errors/92a030744fd5adc3.json. Report an issue: GitHub.