{"record":{"id":"774c053d13fa77c4","repo":"jestjs/jest","slug":"whoops-two-projects-resolved-to-the-same-config-p","errorCode":null,"errorMessage":"Whoops! Two projects resolved to the same config path: ${chalk.bold(String(configPath))}:\n\n  Project 1: ${chalk.bold(projects[parsedConfigs.indexOf(config)])}\n  Project 2: ${chalk.bold(projects[parsedConfigs.indexOf(configPathMap.get(configPath))])}\n\nThis usually means that your ${chalk.bold('\"projects\"')} config includes a directory that doesn't have any configuration recognizable by Jest. Please fix it.\n","messagePattern":"Whoops! Two projects resolved to the same config path: (.+?):\n\n  Project 1: (.+?)\n  Project 2: (.+?)\n\nThis usually means that your (.+?) config includes a directory that doesn't have any configuration recognizable by Jest\\. Please fix it\\.\n","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-config/src/index.ts","lineNumber":296,"sourceCode":"  for (const config of parsedConfigs) {\n    const {configPath} = config;\n\n    if (configPathMap.has(configPath)) {\n      const message = `Whoops! Two projects resolved to the same config path: ${chalk.bold(\n        String(configPath),\n      )}:\n\n  Project 1: ${chalk.bold(projects[parsedConfigs.indexOf(config)])}\n  Project 2: ${chalk.bold(\n    projects[parsedConfigs.indexOf(configPathMap.get(configPath))],\n  )}\n\nThis usually means that your ${chalk.bold(\n        '\"projects\"',\n      )} config includes a directory that doesn't have any configuration recognizable by Jest. Please fix it.\n`;\n\n      throw new Error(message);\n    }\n    if (configPath !== null) {\n      configPathMap.set(configPath, config);\n    }\n  }\n};\n\nexport interface ReadJestConfigOptions {\n  /**\n   * The package root or deserialized config (default is cwd)\n   */\n  packageRootOrConfig?: string | Config.InitialOptions;\n  /**\n   * When the `packageRootOrConfig` contains config, this parameter should\n   * contain the dirname of the parent config\n   */\n  parentConfigDirname?: null | string;\n  /**","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-config/src/index.ts#L278-L314","documentation":"ensureNoDuplicateConfigs (index.ts:268-302) walks each parsed project in a multi-project setup and records its resolved configPath; if two projects map to the same path, it throws. This typically happens when a projects entry is a directory with no Jest-recognizable config, so Jest falls back to resolving the SAME parent config for both — collapsing what you intended as distinct projects into one.","triggerScenarios":"projects: ['packages/a', 'packages/b'] where one directory lacks its own jest.config.*; two project paths that both resolve up to the root config; a glob in projects that yielded overlapping directories.","commonSituations":"Monorepo where a new package was added without a jest.config; projects pointing at empty/non-config directories; naming two project paths identically after normalization; mixing absolute and relative paths that resolve to the same location.","solutions":["Ensure each project directory listed in projects has its own jest.config.{js,ts,...} or a package.json with a jest key.","Give each project a unique displayName so they are distinguishable.","Check the two project paths reported in the message — the duplicate usually means one of them has no config and is inheriting the root.","If a directory should share the root config intentionally, remove it from the projects array (the root already covers it)."],"exampleFix":"// before (packages/b has no jest.config)\nmodule.exports = { projects: ['packages/a', 'packages/b'] };\n// after\n// add packages/b/jest.config.js with at least module.exports = { displayName: 'b' };","handlingStrategy":"validation","validationCode":"import * as fs from 'node:fs';\nimport * as path from 'node:path';\nconst EXTS = ['.js','.ts','.mjs','.cjs','.json','.mts','.cts'];\nfunction assertEachProjectHasConfig(projects: string[]): void {\n  for (const dir of projects) {\n    const hasCfg = fs.existsSync(path.join(dir, 'package.json')) && require(path.join(dir,'package.json')).jest\n      || EXTS.some(e => fs.existsSync(path.join(dir, `jest.config${e}`)));\n    if (!hasCfg) throw new Error(`Project ${dir} has no jest config; add one or remove from projects`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In a monorepo, give every package its own jest.config with a unique displayName.","Run jest --showConfig to confirm each project resolves to a distinct config path.","Avoid listing the root directory as both root and a projects entry."],"tags":["jest-config","multi-project","duplicate-config","monorepo"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}