{"record":{"id":"6090a8ac4f9e3a4d","repo":"withastro/astro","slug":"collection-contains-multiple-entries-with-t-6090a8","errorCode":null,"errorMessage":"**${collection}** contains multiple entries with the same slug: `${slug}`. Slugs must be unique.\n\nEntries: \n- ${preExisting}\n- ${alsoFound}","messagePattern":"\\*\\*(.+?)\\*\\* contains multiple entries with the same slug: `(.+?)`\\. Slugs must be unique\\.\n\nEntries: \n- (.+?)\n- (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/astro/src/content/loaders/glob.ts","lineNumber":203,"sourceCode":"\n\t\t\t\tif (existingEntry && existingEntry.filePath && existingEntry.filePath !== relativePath) {\n\t\t\t\t\t// Check the old file still exists - if not, this is likely a rename and\n\t\t\t\t\t// the unlink event just hasn't been processed yet\n\t\t\t\t\tconst oldFilePath = new URL(existingEntry.filePath, config.root);\n\t\t\t\t\tif (existsSync(oldFilePath)) {\n\t\t\t\t\t\tconst message = AstroErrorData.DuplicateContentEntrySlugError.message(\n\t\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\texistingEntry.filePath,\n\t\t\t\t\t\t\trelativePath,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (config.prerenderConflictBehavior === 'error') {\n\t\t\t\t\t\t\tthrow new AstroError({\n\t\t\t\t\t\t\t\t...AstroErrorData.DuplicateContentEntrySlugError,\n\t\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (config.prerenderConflictBehavior !== 'ignore') {\n\t\t\t\t\t\t\tlogger.warn(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (entryType.getRenderFunction && !globOptions.deferRender) {\n\t\t\t\t\tlet render = renderFunctionByContentType.get(entryType);\n\n\t\t\t\t\tif (!render) {\n\t\t\t\t\t\trender = await entryType.getRenderFunction(config);\n\t\t\t\t\t\t// Cache the render function for this content type, so it can re-use parsers and other expensive setup\n\t\t\t\t\t\trenderFunctionByContentType.set(entryType, render);\n\t\t\t\t\t}\n\t\t\t\t\tlet rendered: RenderedContent | undefined = undefined;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\trendered = await render?.({\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\tdata,","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/withastro/astro/blob/e294953aa8aadd98d5be92e60a03037b05dbdfd4/packages/astro/src/content/loaders/glob.ts#L185-L221","documentation":"Two distinct files ingested by the glob() loader generated the same entry id (from id/slug frontmatter or filename slugification), so the second entry overwrites the first in the store. The astro.config option prerenderConflictBehavior (default 'warn') decides whether this throws an AstroError with the DuplicateContentEntrySlugError message, logs a warning, or is ignored.","triggerScenarios":"foo.md carrying `slug: bar` in frontmatter alongside an existing bar.md; two files in different matched directories whose generated slugs collide; stale ids left in the store after renames (the loader separately handles oldId deletion on watch events).","commonSituations":"Explicit frontmatter slugs that match other filenames; case-insensitive filesystems colliding with case-sensitive slugs; content merges introducing duplicate slugs.","solutions":["Uniquify the frontmatter slug or the filename of the colliding entry","Set prerenderConflictBehavior: 'error' in astro.config.mjs to surface collisions as build failures","Restart the dev server so stale ids from renamed files are cleaned from the store"],"exampleFix":"# before: src/data/blog/bar.md has frontmatter slug: bar, and src/data/blog/foo.md also sets slug: bar\n# after: src/data/blog/foo.md\n---\ntitle: Foo\nslug: foo\n---","handlingStrategy":"validation","validationCode":"// Scan frontmatter slugs + filenames for collisions before build\nimport { readFileSync, readdirSync } from 'node:fs';\nimport matter from 'gray-matter';\nfunction duplicateSlugs(dir: string): string[] {\n  const slugs = readdirSync(dir)\n    .filter((f) => f.endsWith('.md'))\n    .map((f) => (matter(readFileSync(`${dir}/${f}`, 'utf-8')).data as any).slug ?? f.replace(/\\.md$/, ''));\n  return [...new Set(slugs.filter((s, i) => slugs.indexOf(s) !== i))];\n}","typeGuard":null,"tryCatchPattern":"// With prerenderConflictBehavior: 'error', slug collisions throw during build:\nimport { AstroError } from 'astro';\ntry {\n  await runBuild();\n} catch (err) {\n  if (err instanceof AstroError && err.name === 'DuplicateContentEntrySlugError') {\n    // the message lists the collection and both colliding file paths\n    console.error(err.message);\n    process.exitCode = 1;\n  } else throw err;\n}","preventionTips":["Derive slugs from filenames only, or keep frontmatter slugs unique by convention","Enable prerenderConflictBehavior: 'error' in CI to catch collisions as hard failures","Restart the dev server after bulk renames so stale ids leave the store"],"tags":["astro","content-collections","glob-loader","duplicate-slug","slug-conflict"],"backgroundTag":"duplicate-content-slug","analyzedSha":"e294953aa8aadd98d5be92e60a03037b05dbdfd4","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}