{"record":{"id":"be03267250a6f57c","repo":"facebook/docusaurus","slug":"plugin-not-found-for-identifier-formatpluginname","errorCode":null,"errorMessage":"Plugin not found for identifier ${formatPluginName(pluginIdentifier)}","messagePattern":"Plugin not found for identifier (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/docusaurus/src/server/plugins/pluginsUtils.ts","lineNumber":32,"sourceCode":"  LoadedPlugin,\n  PluginIdentifier,\n  PluginRouteConfig,\n  RouteConfig,\n} from '@docusaurus/types';\n\nexport function getPluginByIdentifier<P extends InitializedPlugin>({\n  plugins,\n  pluginIdentifier,\n}: {\n  pluginIdentifier: PluginIdentifier;\n  plugins: P[];\n}): P {\n  const plugin = plugins.find(\n    (p) =>\n      p.name === pluginIdentifier.name && p.options.id === pluginIdentifier.id,\n  );\n  if (!plugin) {\n    throw new Error(\n      logger.interpolate`Plugin not found for identifier ${formatPluginName(\n        pluginIdentifier,\n      )}`,\n    );\n  }\n  return plugin;\n}\n\nexport function aggregateAllContent(loadedPlugins: LoadedPlugin[]): AllContent {\n  return _.chain(loadedPlugins)\n    .groupBy((item) => item.name)\n    .mapValues((nameItems) =>\n      _.chain(nameItems)\n        .groupBy((item) => item.options.id)\n        .mapValues((idItems) => idItems[0]!.content)\n        .value(),\n    )\n    .value();","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/facebook/docusaurus/blob/3f483e80e326cc646b54b83d564b3f0c4881b9a6/packages/docusaurus/src/server/plugins/pluginsUtils.ts#L14-L50","documentation":"Thrown by `getPluginByIdentifier` when no loaded plugin matches both the requested `name` and `options.id`. Plugins are keyed by a (name, id) tuple; looking up a non-existent combination is a hard failure used internally by routing, content aggregation, and CLI commands.","triggerScenarios":"Calling an internal helper that resolves a plugin by identifier (e.g. for `--config` of a specific plugin instance, or for translation collection) with a name/id pair that was never initialized. The `plugins.find(...)` at pluginsUtils.ts:25-30 returns undefined and the throw at :31-37 fires.","commonSituations":"Referencing a plugin id that was renamed or removed; passing a wrong plugin name to a CLI flag; mismatched id between config and a downstream tool/theme that calls this helper.","solutions":["Verify the plugin name and id against your docusaurus.config.js (print loaded plugins if needed).","Fix typos in the identifier (name or id).","Ensure the target plugin is actually registered (not disabled by a preset)."],"exampleFix":"// before\nconst p = getPluginByIdentifier({\n  plugins,\n  pluginIdentifier: {name: 'content-docs', id: 'secondary'},\n});\n// after (id corrected)\nconst p = getPluginByIdentifier({\n  plugins,\n  pluginIdentifier: {name: 'content-docs', id: 'other'},\n});","handlingStrategy":"type-guard","validationCode":"function pluginExists(plugins, id: {name: string; id?: string}) {\n  return plugins.some(p => p.name === id.name && p.options.id === (id.id ?? 'default'));\n}","typeGuard":"function findPlugin<P extends InitializedPlugin>(plugins: P[], id: PluginIdentifier): P | undefined {\n  return plugins.find(p => p.name === id.name && p.options.id === id.id);\n}","tryCatchPattern":"const plugin = plugins.find(p => p.name === id.name && p.options.id === id.id);\nif (!plugin) { /* graceful fallback instead of throwing */ }","preventionTips":["Validate plugin identifiers against loaded plugins before lookups.","Centralize plugin id constants to avoid typos.","Log loaded plugin (name, id) tuples at startup for debugging."],"tags":["plugins","lookup","config"],"backgroundTag":null,"analyzedSha":"3f483e80e326cc646b54b83d564b3f0c4881b9a6","analyzedAt":"2026-08-12T13:25:04.382Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}