{"record":{"id":"7a1e54ddbf44b448","repo":"facebook/docusaurus","slug":"looks-like-the-changelog-plugin-didn-t-detect-docu","errorCode":null,"errorMessage":"Looks like the changelog plugin didn't detect Docusaurus changelog files","messagePattern":"Looks like the changelog plugin didn't detect Docusaurus changelog files","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"website/src/plugins/changelog/index.ts","lineNumber":32,"sourceCode":"  normalizeUrl,\n  safeGlobby,\n} from '@docusaurus/utils';\nimport {createBlogFiles, toChangelogEntries} from './utils';\n\nexport {validateOptions} from '@docusaurus/plugin-content-blog';\n\nconst MonorepoRoot = path.resolve(path.join(__dirname, '../../../..'));\n\nconst ChangelogFilePattern = 'CHANGELOG(-v[0-9]*)?.md';\n\nasync function getChangelogFiles() {\n  const files = await safeGlobby([ChangelogFilePattern], {\n    cwd: MonorepoRoot,\n  });\n  // As of today, there are 2 changelog files\n  // and this is only going to increase\n  if (files.length < 2) {\n    throw new Error(\n      \"Looks like the changelog plugin didn't detect Docusaurus changelog files\",\n    );\n  }\n  // Note: the returned file order doesn't matter.\n  return files;\n}\n\nfunction readChangelogFile(filename: string) {\n  return fs.readFile(path.join(MonorepoRoot, filename), 'utf-8');\n}\n\nasync function loadChangelogEntries(changelogFiles: string[]) {\n  const filesContent = await Promise.all(changelogFiles.map(readChangelogFile));\n  return toChangelogEntries(filesContent);\n}\n\nconst ChangelogPlugin: typeof pluginContentBlog =\n  async function ChangelogPlugin(context, options) {","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/facebook/docusaurus/blob/3f483e80e326cc646b54b83d564b3f0c4881b9a6/website/src/plugins/changelog/index.ts#L14-L50","documentation":"Thrown by getChangelogFiles() in the Docusaurus website's custom changelog plugin when safeGlobby finds fewer than 2 files matching `CHANGELOG(-v[0-9]*)?.md` at the monorepo root (path.resolve(__dirname, '../../../..')). The plugin expects at least the main CHANGELOG.md plus one versioned CHANGELOG-vN.md. This is an internal safeguard for the Docusaurus project's own website, not a user-facing API.","triggerScenarios":"Building the Docusaurus website when CHANGELOG files are missing, gitignored in a way that globby skips them, renamed, or when the monorepo root resolution (../../../..  from website/src/plugins/changelog) is wrong due to a moved file.","commonSituations":"Running the website build in a shallow/partial checkout that excluded CHANGELOG files; a repo restructure that moved the changelog plugin or changed the monorepo layout; someone deleted a versioned changelog during a cleanup.","solutions":["Confirm CHANGELOG.md and at least one CHANGELOG-vN.md exist at the monorepo root: `ls CHANGELOG*.md`.","If files were renamed, either restore the expected names or update ChangelogFilePattern to match.","If the plugin file moved, fix the relative '../../../..' in MonorepoRoot so it still points at the repo root.","For your own project this plugin is not used — only the Docusaurus repo's own website hits this; copy the pattern but adjust the threshold/pattern to your project."],"exampleFix":"// before\nconst ChangelogFilePattern = 'CHANGELOG(-v[0-9]*)?.md';\nif (files.length < 2) { throw ... }\n// after (adjust to your project's reality)\nconst ChangelogFilePattern = 'CHANGES.md';\nif (files.length < 1) { throw ... }","handlingStrategy":"validation","validationCode":"import fs from 'fs-extra';\nimport path from 'path';\n\nasync function assertChangelogFiles(root: string, minCount = 2) {\n  const {default: globby} = await import('globby');\n  const files = await globby(['CHANGELOG(-v[0-9]*)?.md'], {cwd: root});\n  if (files.length < minCount) {\n    throw new Error(\n      `Expected >= ${minCount} changelog files at ${root}, found ${files.length}: ${files.join(', ') || 'none'}`,\n    );\n  }\n}\n\n// await assertChangelogFiles(path.resolve(__dirname, '../../..'));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pin the expected changelog file names in CI with a file-existence check before building the website.","If you fork this plugin, set ChangelogFilePattern and the min threshold to match your project's reality."],"tags":["changelog","website-internal","plugin","filesystem"],"backgroundTag":null,"analyzedSha":"3f483e80e326cc646b54b83d564b3f0c4881b9a6","analyzedAt":"2026-08-12T13:25:04.382Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}