facebook/docusaurus · error · Error
Plugin not found for identifier ${formatPluginName(pluginIde
Error message
Plugin not found for identifier ${formatPluginName(pluginIdentifier)} What it means
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.
Source
Thrown at packages/docusaurus/src/server/plugins/pluginsUtils.ts:32
LoadedPlugin,
PluginIdentifier,
PluginRouteConfig,
RouteConfig,
} from '@docusaurus/types';
export function getPluginByIdentifier<P extends InitializedPlugin>({
plugins,
pluginIdentifier,
}: {
pluginIdentifier: PluginIdentifier;
plugins: P[];
}): P {
const plugin = plugins.find(
(p) =>
p.name === pluginIdentifier.name && p.options.id === pluginIdentifier.id,
);
if (!plugin) {
throw new Error(
logger.interpolate`Plugin not found for identifier ${formatPluginName(
pluginIdentifier,
)}`,
);
}
return plugin;
}
export function aggregateAllContent(loadedPlugins: LoadedPlugin[]): AllContent {
return _.chain(loadedPlugins)
.groupBy((item) => item.name)
.mapValues((nameItems) =>
_.chain(nameItems)
.groupBy((item) => item.options.id)
.mapValues((idItems) => idItems[0]!.content)
.value(),
)
.value();View on GitHub (pinned to 3f483e80e3)
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).
Example fix
// before
const p = getPluginByIdentifier({
plugins,
pluginIdentifier: {name: 'content-docs', id: 'secondary'},
});
// after (id corrected)
const p = getPluginByIdentifier({
plugins,
pluginIdentifier: {name: 'content-docs', id: 'other'},
}); Defensive patterns
Strategy: type-guard
Validate before calling
function pluginExists(plugins, id: {name: string; id?: string}) {
return plugins.some(p => p.name === id.name && p.options.id === (id.id ?? 'default'));
} Type guard
function findPlugin<P extends InitializedPlugin>(plugins: P[], id: PluginIdentifier): P | undefined {
return plugins.find(p => p.name === id.name && p.options.id === id.id);
} Try / catch
const plugin = plugins.find(p => p.name === id.name && p.options.id === id.id);
if (!plugin) { /* graceful fallback instead of throwing */ } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- A Docusaurus plugin returned 'undefined', which is forbidden
- A Docusaurus plugin is missing a 'name' property.\nNote that
- Plugin "${pluginName}" is used ${pluginInstancesWithId.lengt
- Translation file path at "${translationFilePath}" does not n
- You can't use siteConfig.webpack.jsLoader and siteConfig.fut
AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12).
Data as JSON: /api/errors/be03267250a6f57c.
Report an issue: GitHub.