facebook/docusaurus · error · Error

Plugin "${pluginName}" is used ${pluginInstancesWithId.lengt

Error message

Plugin "${pluginName}" is used ${pluginInstancesWithId.length} times with ID "${pluginId}".\nTo use the same plugin multiple times on a Docusaurus site, you need to assign a unique ID to each plugin instance.${pluginId === DEFAULT_PLUGIN_ID ? `\n\nThe plugin ID is "${DEFAULT_PLUGIN_ID}" by default. It's possible that the preset you are using already includes a plugin instance, in which case you either want to disable the plugin in the preset (to use a single instance), or assign another ID to your extra plugin instance (to use multiple instances).` : ''}

What it means

Thrown by `ensureUniquePluginInstanceIds` after initialization when two or more loaded plugins share the same `name` AND the same `options.id` (defaulting to `'default'`). Docusaurus needs each plugin instance to have a unique (name, id) tuple to namespace data and routes. The message specially hints when the collision is on the default id, since that often means a preset already registered the plugin.

Source

Thrown at packages/docusaurus/src/server/plugins/pluginIds.ts:28

import type {InitializedPlugin} from '@docusaurus/types';

/**
 * It is forbidden to have 2 plugins of the same name sharing the same ID.
 * This is required to support multi-instance plugins without conflict.
 */
export function ensureUniquePluginInstanceIds(
  plugins: InitializedPlugin[],
): void {
  const pluginsByName = _.groupBy(plugins, (p) => p.name);
  Object.entries(pluginsByName).forEach(([pluginName, pluginInstances]) => {
    const pluginInstancesById = _.groupBy(
      pluginInstances,
      (p) => p.options.id ?? DEFAULT_PLUGIN_ID,
    );
    Object.entries(pluginInstancesById).forEach(
      ([pluginId, pluginInstancesWithId]) => {
        if (pluginInstancesWithId.length !== 1) {
          throw new Error(
            `Plugin "${pluginName}" is used ${
              pluginInstancesWithId.length
            } times with ID "${pluginId}".\nTo use the same plugin multiple times on a Docusaurus site, you need to assign a unique ID to each plugin instance.${
              pluginId === DEFAULT_PLUGIN_ID
                ? `\n\nThe plugin ID is "${DEFAULT_PLUGIN_ID}" by default. It's possible that the preset you are using already includes a plugin instance, in which case you either want to disable the plugin in the preset (to use a single instance), or assign another ID to your extra plugin instance (to use multiple instances).`
                : ''
            }`,
          );
        }
      },
    );
  });
}

View on GitHub (pinned to 3f483e80e3)

Solutions

  1. Give each duplicate instance a unique `id` in its options (e.g. `{id: 'community', path: 'community/docs'}`).
  2. If you only want one instance, disable the preset's copy (e.g. `presets: [['classic', {docs: false}]]`) and keep your explicit one.
  3. Remove the redundant plugin entry entirely.

Example fix

// before
presets: [['classic', {}]],
plugins: [['@docusaurus/plugin-content-docs', {path: 'other-docs'}]],
// after
presets: [['classic', {}]],
plugins: [['@docusaurus/plugin-content-docs', {id: 'other', path: 'other-docs'}]],
Defensive patterns

Strategy: validation

Validate before calling

function assertUniqueIds(plugins: Array<{name: string; options: {id?: string}}>) {
  const seen = new Set<string>();
  for (const p of plugins) {
    const key = `${p.name}:${p.options.id ?? 'default'}`;
    if (seen.has(key)) throw new Error(`Duplicate plugin id: ${key}`);
    seen.add(key);
  }
}

Prevention

When it happens

Trigger: Listing the same plugin twice without distinct `id` options; adding a plugin in `plugins:` that a preset already injects under the default id. The check at pluginIds.ts:25-44 groups by name then by id and throws when a group has length !== 1.

Common situations: Using `@docusaurus/plugin-content-docs` both via preset-classic and again explicitly; multi-instance plugins (blog, docs) where the user forgot `id: 'secondary'`; copying a plugin entry in config.

Related errors


AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12). Data as JSON: /api/errors/a9ed24c4cf00368c. Report an issue: GitHub.