{"record":{"id":"9cb5a7be853689b5","repo":"facebook/docusaurus","slug":"a-docusaurus-plugin-is-missing-a-name-property","errorCode":null,"errorMessage":"A Docusaurus plugin is missing a 'name' property.\\nNote that even inline/anonymous plugin functions require a 'name' property.","messagePattern":"A Docusaurus plugin is missing a 'name' property\\.\\\\nNote that even inline/anonymous plugin functions require a 'name' property\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/docusaurus/src/server/plugins/init.ts","lineNumber":160,"sourceCode":"      pluginOptions,\n    );\n\n    // Returning null has been explicitly allowed\n    // It's a way for plugins to self-disable depending on context\n    // See https://github.com/facebook/docusaurus/pull/10286\n    if (pluginInstance === null) {\n      return {config: normalizedPluginConfig, plugin: null};\n    }\n    if (pluginInstance === undefined) {\n      throw new Error(\n        `A Docusaurus plugin returned 'undefined', which is forbidden.\nA plugin is expected to return an object having at least a 'name' property.\nIf you want a plugin to self-disable depending on context/options, you can explicitly return 'null' instead of 'undefined'`,\n      );\n    }\n\n    if (!pluginInstance?.name) {\n      throw new Error(\n        `A Docusaurus plugin is missing a 'name' property.\nNote that even inline/anonymous plugin functions require a 'name' property.`,\n      );\n    }\n\n    const plugin: InitializedPlugin = {\n      ...pluginInstance,\n      options: pluginOptions,\n      version: pluginVersion,\n      path: path.dirname(normalizedPluginConfig.entryPath),\n    };\n\n    return {\n      config: normalizedPluginConfig,\n      plugin,\n    };\n  }\n","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/facebook/docusaurus/blob/3f483e80e326cc646b54b83d564b3f0c4881b9a6/packages/docusaurus/src/server/plugins/init.ts#L142-L178","documentation":"Thrown during plugin initialization when the plugin returns a non-null object that lacks a `name` property. Docusaurus relies on `name` to namespace plugin content, options, and IDs; anonymous plugins break that contract. Even inline plugin functions must declare a `name`. The check is at plugins/init.ts:158-163.","triggerScenarios":"Returning `{ loadContent: ... }` without `name`; assigning the plugin object from a spread that omits `name`; an inline plugin function literal whose body returns a nameless object.","commonSituations":"Quick prototyping an inline plugin in docusaurus.config.js; refactoring a plugin module and dropping the `name` export; copying a snippet that omitted `name`.","solutions":["Add a stable `name` string to the returned plugin object (e.g. `'my-plugin'`).","For function plugins, give the function itself a `name` (function declaration) — but explicit `name` in the returned object is safest.","Use the `Plugin` type from `@docusaurus/types` to make missing `name` a compile error."],"exampleFix":"// before\nplugins: [() => ({ loadContent: () => null })],\n// after\nplugins: [() => ({ name: 'my-plugin', loadContent: () => null })],","handlingStrategy":"type-guard","validationCode":"function assertPluginName(p: unknown) {\n  if (!p || typeof (p as any).name !== 'string') {\n    throw new Error('Plugin object must include a string `name`');\n  }\n}","typeGuard":"function hasPluginName(p: unknown): p is {name: string} {\n  return typeof p === 'object' && p !== null && typeof (p as any).name === 'string';\n}","tryCatchPattern":null,"preventionTips":["Type plugin returns as `Plugin` from `@docusaurus/types`.","Always include an explicit `name` in the returned object, not just on the function.","Add a tiny unit test asserting `name` is present for each plugin."],"tags":["plugins","config","contracts"],"backgroundTag":null,"analyzedSha":"3f483e80e326cc646b54b83d564b3f0c4881b9a6","analyzedAt":"2026-08-12T13:25:04.382Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}