jestjs/jest · error · Error

Cannot find module

Error message

Cannot find module '${presetPath}'

What it means

setupPreset in normalize.ts (lines 170-237) resolves the preset name via Resolver.findNodeModule and requires the result. If findNodeModule returns null (line 187), it throws this raw 'Cannot find module' error; the surrounding catch (lines 197-236) then rewraps it into a more helpful createConfigError that distinguishes missing-preset, missing-jest-preset-file, and missing-dependency cases. The raw message surfaces when the catch hasn't yet translated it.

Solutions

  1. Install the preset package: npm install --save-dev <preset-name>.
  2. Verify the preset exports jest-preset.js or jest-preset.json at its root.
  3. Check rootDir in your config — preset paths resolve relative to it.
  4. For local/relative presets, use a path starting with ./ or an absolute path.

Example fix

// before
module.exports = { preset: 'my-preset' }; // not installed
// after
npm install --save-dev my-preset
// or relative:
module.exports = { preset: './my-preset' };
Defensive patterns

Strategy: validation

Validate before calling

import { Resolver } from 'jest-resolve';
function ensurePresetExists(rootDir: string, preset: string): void {
  const path = preset.startsWith('.') || require('node:path').isAbsolute(preset) ? preset : `${preset}/jest-preset`;
  const mod = Resolver.findNodeModule(path, { basedir: rootDir });
  if (!mod) throw new Error(`Preset '${preset}' not resolvable from ${rootDir}`);
}

Try / catch

try {
  await normalize(options, argv, configPath, ...);
} catch (e) {
  if (/Cannot find module/.test((e as Error).message)) {
    console.error('Preset missing — did you install it?', e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Setting preset: 'foo' where 'foo' is not installed; preset path with a typo; preset resolving against the wrong rootDir; relative preset path that doesn't exist; a preset whose package.json lacks a jest-preset.js/json entry.

Common situations: Forgetting to npm install the preset package; monorepo rootDir misconfiguration so resolution happens from the wrong base; upgrading and removing a preset dependency; scoped package name typo (e.g. @scope/preset vs @scope/jest-preset).

Related errors


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

Appendix: source

Thrown at packages/jest-config/src/normalize.ts:188

const setupPreset = async (
  options: Config.InitialOptionsWithRootDir,
  optionsPreset: string,
): Promise<Config.InitialOptionsWithRootDir> => {
  let preset: Config.InitialOptions;
  const presetPath = replaceRootDirInPath(options.rootDir, optionsPreset);
  const presetModule = Resolver.findNodeModule(
    presetPath.startsWith('.') || path.isAbsolute(presetPath)
      ? presetPath
      : `${presetPath}/${PRESET_NAME}`,
    {
      basedir: options.rootDir,
      extensions: PRESET_EXTENSIONS,
    },
  );

  try {
    if (!presetModule) {
      throw new Error(`Cannot find module '${presetPath}'`);
    }

    // Force re-evaluation to support multiple projects
    try {
      delete require.cache[require.resolve(presetModule)];
    } catch {}

    preset = await requireOrImportModule(presetModule);
  } catch (error: any) {
    if (error instanceof SyntaxError || error instanceof TypeError) {
      throw createConfigError(
        `  Preset ${chalk.bold(presetPath)} is invalid:\n\n  ${
          error.message
        }\n  ${error.stack}`,
      );
    }

    if (error.message.includes('Cannot find module')) {

View on GitHub (pinned to 8e6d128e4a)