{"id":"58a6603753db9418","repo":"jestjs/jest","slug":"duplicated-files-or-mocks-please-check-the-consol","errorCode":null,"errorMessage":"Duplicated files or mocks. Please check the console for more info","messagePattern":"Duplicated files or mocks\\. Please check the console for more info","errorType":"exception","errorClass":"DuplicateError","httpStatus":null,"severity":"error","filePath":"packages/jest-haste-map/src/lib/FileProcessor.ts","lineNumber":106,"sourceCode":"        H.GENERIC_PLATFORM;\n\n      const existingModule = moduleMap[platform];\n\n      if (existingModule && existingModule[H.PATH] !== module[H.PATH]) {\n        const method = this._options.throwOnModuleCollision ? 'error' : 'warn';\n\n        this._console[method](\n          [\n            `jest-haste-map: Haste module naming collision: ${id}`,\n            '  The following files share their name; please adjust your hasteImpl:',\n            `    * <rootDir>${path.sep}${existingModule[H.PATH]}`,\n            `    * <rootDir>${path.sep}${module[H.PATH]}`,\n            '',\n          ].join('\\n'),\n        );\n\n        if (this._options.throwOnModuleCollision) {\n          throw new DuplicateError(existingModule[H.PATH], module[H.PATH]);\n        }\n\n        // We do NOT want consumers to use a module that is ambiguous.\n        delete moduleMap[platform];\n\n        if (Object.keys(moduleMap).length === 0) {\n          map.delete(id);\n        }\n\n        let dupsByPlatform = hasteMap.duplicates.get(id);\n        if (dupsByPlatform == null) {\n          dupsByPlatform = new Map();\n          hasteMap.duplicates.set(id, dupsByPlatform);\n        }\n\n        const dups = new Map([\n          [module[H.PATH], module[H.TYPE]],\n          [existingModule[H.PATH], existingModule[H.TYPE]],","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-haste-map/src/lib/FileProcessor.ts#L88-L124","documentation":"While processing each file, FileProcessor.assigns haste module IDs. When two different file paths resolve to the same haste ID on the same platform (a naming collision), and the `throwOnModuleCollision` option is true, it throws a DuplicateError whose message is generic but whose mockPath1/mockPath2 carry the colliding paths. The console also receives a detailed 'Haste module naming collision' message immediately before the throw.","triggerScenarios":"processFile() → setModule() finds existingModule[H.PATH] !== module[H.PATH] for the same id+platform (FileProcessor.ts:92); throwOnModuleCollision is true (line 105 → 106). The duplicate typically comes from two files that a hasteImpl (or platform extension resolution) maps to the same module name.","commonSituations":"Two files with the same @providesModule / haste name; an RN-style module duplicated across vendor forks; enabling throwOnModuleCollision in CI to enforce uniqueness; a buggy custom hasteImplModulePath returning colliding names; copying a file without renaming its haste header.","solutions":["Read the console output immediately preceding the throw — it lists both colliding paths and the shared id; rename one file or update its haste header.","If the duplicate is intentional (platform-specific variants), confirm the platform extension is correct so they land on different platforms.","If using a custom hasteImplModulePath, debug its getHasteName return value for the two paths.","If collisions are acceptable in your workflow, set throwOnModuleCollision:false (Jest then warns and drops the ambiguous entry)."],"exampleFix":"// before — two files both declare `@providesModule Button`\n// src/Button.js      -> Button\n// src/legacy/Button.js -> Button  (collision)\n\n// after — rename one haste module\n// src/legacy/Button.js -> `@providesModule LegacyButton`","handlingStrategy":"validation","validationCode":"// Before enabling throwOnModuleCollision, scan for duplicate haste IDs.\n// Example: gather @providesModule names and report duplicates without throwing.\nimport {readFileSync} from 'node:fs';\nconst names = new Map(); // name -> [files]\nfor (const f of fileList) {\n  const m = /@providesModule\\s+(\\S+)/.exec(readFileSync(f, 'utf8'));\n  if (m) names.set(m[1], [...(names.get(m[1]) ?? []), f]);\n}\nconst dupes = [...names.entries()].filter(([, files]) => files.length > 1);\nif (dupes.length) console.warn('haste collisions:', dupes);","typeGuard":null,"tryCatchPattern":"import {DuplicateError} from 'jest-haste-map';\ntry {\n  await hasteMap.build();\n} catch (err) {\n  if (err instanceof DuplicateError) {\n    console.error('collision between', err.mockPath1, 'and', err.mockPath2);\n  }\n  throw err;\n}","preventionTips":["Run a duplicate-haste-ID scan in CI before enabling throwOnModuleCollision.","Keep throwOnModuleCollision:false locally (warn) and true only in CI to fail on collisions without blocking dev.","Use platform extensions correctly so platform variants do not collide on the generic platform."],"tags":["haste-map","module-collision","duplicate","config"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}