{"record":{"id":"cd44e9c67b470129","repo":"vitest-dev/vitest","slug":"project-name-name-from-entryfile-is-not","errorCode":null,"errorMessage":"Project name \"${name}\" from \"${entryFile}\" is not unique. The project is already defined by \"${existingFile}\". All projects should have unique names. Make sure your configuration is correct.","messagePattern":"Project name \"(.+?)\" from \"(.+?)\" is not unique\\. The project is already defined by \"(.+?)\"\\. All projects should have unique names\\. Make sure your configuration is correct\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/projects/resolveProjects.ts","lineNumber":173,"sourceCode":"      // inline entries carry the configFile they extend, which doesn't say\n      // where the project is declared, so they are reported without a file\n      const entryFile = !entry.inline && entry.viteConfig.configFile\n        ? relative(globalConfig.root, entry.viteConfig.configFile)\n        : ''\n      const existingFile = !existing.inline && existing.viteConfig.configFile\n        ? relative(globalConfig.root, existing.viteConfig.configFile)\n        : ''\n      const filesError = baseEntries.length > 1 && (entryFile || existingFile)\n        ? [\n            '\\n\\nYour config matched these files:\\n',\n            baseEntries\n              .filter(e => !e.inline && e.viteConfig.configFile)\n              .map(e => ` - ${relative(globalConfig.root, e.viteConfig.configFile as string)}`)\n              .join('\\n'),\n            '\\n\\n',\n          ].join('')\n        : ' '\n      throw new Error([\n        `Project name \"${name}\"`,\n        entryFile ? ` from \"${entryFile}\"` : '',\n        ' is not unique.',\n        existingFile ? ` The project is already defined by \"${existingFile}\".` : '',\n        filesError,\n        'All projects should have unique names. Make sure your configuration is correct.',\n      ].join(''))\n    }\n    seenNames.set(name, entry)\n  }\n  const seenNamesSet = new Set(seenNames.keys())\n\n  // Browser instance expansion (per-entry config injection).\n  const afterBrowser = expandBrowserInstancesInEntries(globalConfig, baseEntries, seenNamesSet)\n\n  // Benchmark expansion (per-entry config injection, runs over post-browser list).\n  // `--benchmark` makes every project run as a benchmark.\n  const afterBenchmark = expandBenchmarksInEntries(afterBrowser, seenNamesSet, !!globalConfig.cliOptions.benchmarkOnly)","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/vitest/src/node/projects/resolveProjects.ts#L155-L191","documentation":"The detailed duplicate-name error for file-based project resolution. When two resolved entries share a name and there are multiple config files, Vitest reports the declaring file (entryFile) and the file that first claimed the name (existingFile), plus the list of matched config files, so the user can locate both declarations.","triggerScenarios":"Two non-inline project entries (from different config files) resolve to the same name; baseEntries.length > 1 and at least one has a configFile, producing the file list.","commonSituations":"A glob/workspace matching multiple config files that each define a project with the same name, copy-pasted project configs, or a monorepo where packages reuse a shared name.","solutions":["Rename one of the projects so each config file declares a unique name.","Read the listed config files in the error to find both declarations.","If using globs, ensure each matched config sets a distinct, derived name.","Centralize naming (e.g. derive from directory) to avoid manual collisions."],"exampleFix":"// before - packages/a/vitest.config.ts and packages/b/vitest.config.ts both: test: { name: 'core' }\n// after - packages/b\nexport default defineConfig({ test: { name: 'b-core' } })","handlingStrategy":"validation","validationCode":"// Scan config files for duplicate project names before running.\nimport { globSync } from 'glob'\nfunction findDuplicateProjectNames(configFiles: string[]) {\n  const seen = new Map<string, string>()\n  for (const f of configFiles) {\n  const mod = require(f)\n  const name = mod?.default?.test?.name\n  if (!name) continue\n  if (seen.has(name)) throw new Error(`Duplicate project name \"${name}\" in ${f} (already in ${seen.get(name)})`)\n  seen.set(name, f)\n  }\n}","typeGuard":"const allProjectNamesUnique = (entries: { name: string; file?: string }[]): boolean =>\n  new Set(entries.map(e => e.name)).size === entries.length","tryCatchPattern":null,"preventionTips":["Derive project names from directory/package name to avoid manual collisions.","Add a CI check that asserts unique project names across the workspace.","Use 'vitest list' to audit resolved project names."],"tags":["projects","config","naming","workspace"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}