jestjs/jest · error · DuplicateHasteCandidatesError
The name ` ` was looked up in the Haste module map. It…
Error message
The name `${name}` was looked up in the Haste module map. It cannot be resolved, because there exists several different files, or packages, that provide a module for that particular name and platform. ${platformMessage} You must delete or exclude files until there remains only one of these:
${duplicatesList} What it means
Thrown as `DuplicateHasteCandidatesError` when module resolution finds multiple files or packages providing the same haste module name for the same platform. Jest's haste map requires names to be unique per platform; when duplicates exist, it cannot decide which file to resolve and lists all candidates.
Solutions
- Read the error — it lists all conflicting file paths and their types (module/package).
- Delete, rename, or exclude one of the duplicate files so only one remains for that name+platform.
- Add the conflicting path to `modulePathIgnorePatterns` or ` haste.retainAllFiles: false` scope.
- If duplicates come from node_modules symlinks in a monorepo, configure `haste.enableSymlinks` or dedupe with the package manager.
- Rename the `@providesModule` declaration in one of the files.
Example fix
// before: two files both declare // src/Foo.js /** @providesModule Foo */ // src/components/Foo.js (accidental copy) /** @providesModule Foo */ // after: remove the duplicate or rename it // src/components/Foo.js /** @providesModule NewFoo */
Defensive patterns
Strategy: validation
Validate before calling
// Scan for duplicate @providesModule declarations before running Jest
const fs = require('fs');
const path = require('path');
function findDuplicateHasteNames(rootDir) {
const names = new Map();
function walk(dir) {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
if (entry.name === 'node_modules') continue;
const full = path.join(dir, entry.name);
if (entry.isDirectory()) { walk(full); }
else if (/\.js$/.test(entry.name)) {
const content = fs.readFileSync(full, 'utf8');
const match = content.match(/@providesModule\s+(\S+)/);
if (match) {
if (names.has(match[1])) {
throw new Error(`Duplicate @providesModule ${match[1]}: ${names.get(match[1])} and ${full}`);
}
names.set(match[1], full);
}
}
}
}
walk(rootDir);
} Try / catch
try {
const modulePath = hasteMap.getModule(name, platform);
if (!modulePath) throw new Error(`Cannot resolve module: ${name}`);
} catch (e) {
if (e.constructor.name === 'DuplicateHasteCandidatesError') {
console.error('Haste name collision:', e.hasteName, e.duplicatesSet);
// Guide user to deduplicate
}
throw e;
} Prevention
- Run a duplicate-haste-names scan script before CI in React Native projects.
- Use unique package.json names across all packages in a monorepo.
- Avoid copy-pasting files that contain @providesModule declarations.
- Add duplicate detection to a pre-commit hook or lint step.
- Use modulePathIgnorePatterns to exclude generated/temp directories from the haste map.
When it happens
Trigger: Two files declaring the same `@providesModule` name, two `package.json` files with the same `name` in different directories both reachable by the haste map, or platform-specific files (e.g. `Foo.js` and `Foo.ios.js`) that resolve to the same generic platform. The error is thrown from `_assertNoDuplicates` during `getModule`/`getPackage`.
Common situations: React Native projects where `@providesModule` annotations collide. Monorepo with multiple packages sharing the same npm name. Accidental file duplication (copy-paste). A symlink creating a second path to the same haste-decorated file. Migrating to haste and having leftover declarations.
Related errors
- babel-jest: Babel ignores
- jest-haste-map: enableSymlinks config option was set, but…
- Attempted to display seed but seed value is undefined
- Cannot find module
- Cannot parse as JSON
AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10).
Data as JSON: /api/errors/d80cd4f9c73b950d.
Report an issue: GitHub.
Appendix: source
Thrown at packages/jest-haste-map/src/ModuleMap.ts:191
private _assertNoDuplicates(
name: string,
platform: string,
supportsNativePlatform: boolean,
relativePathSet: DuplicatesSet | null,
) {
if (relativePathSet == null) {
return;
}
// Force flow refinement
const previousSet = relativePathSet;
const duplicates = new Map();
for (const [relativePath, type] of previousSet) {
const duplicatePath = fastPath.resolve(this._raw.rootDir, relativePath);
duplicates.set(duplicatePath, type);
}
throw new DuplicateHasteCandidatesError(
name,
platform,
supportsNativePlatform,
duplicates,
);
}
static create(rootDir: string): ModuleMap {
return new ModuleMap({
duplicates: new Map(),
map: new Map(),
mocks: new Map(),
rootDir,
});
}
}
class DuplicateHasteCandidatesError extends Error {View on GitHub (pinned to 8e6d128e4a)