facebook/docusaurus · error · Error
Docusaurus was unable to resolve the "${moduleName}" ${modul
Error message
Docusaurus was unable to resolve the "${moduleName}" ${moduleType}. Make sure one of the following packages are installed:\n${modulePatterns.map((m) => `- ${m}`).join('\n')} What it means
Thrown by `resolveModuleName` when none of the generated name patterns for a preset/theme/plugin resolve via `require.resolve`. Docusaurus expands a shorthand name (e.g. `'classic'`) into candidate package names and tries each; if all fail, it reports the full candidate list so the user knows exactly which package to install.
Source
Thrown at packages/docusaurus/src/server/plugins/moduleShorthand.ts:48
];
}
export function resolveModuleName(
moduleName: string,
moduleRequire: NodeRequire,
moduleType: 'preset' | 'theme' | 'plugin',
): string {
const modulePatterns = getNamePatterns(moduleName, moduleType);
const module = modulePatterns.find((m) => {
try {
moduleRequire.resolve(m);
return true;
} catch {
return false;
}
});
if (!module) {
throw new Error(`Docusaurus was unable to resolve the "${moduleName}" ${moduleType}. Make sure one of the following packages are installed:
${modulePatterns.map((m) => `- ${m}`).join('\n')}`);
}
return module;
}
View on GitHub (pinned to 3f483e80e3)
Solutions
- Install the missing package: `npm install @docusaurus/preset-classic` (use the exact name from the error's candidate list).
- Fix typos in the preset/plugin string.
- For local plugins, pass the resolved path (`require.resolve('./my-plugin')`) instead of a package name.
- In a monorepo, ensure the package is built (`pnpm --filter <pkg> build`) and resolvable from the site dir.
Example fix
// before presets: ['classic'], // but @docusaurus/preset-classic not installed // after (install first) // npm i @docusaurus/preset-classic presets: ['classic'],
Defensive patterns
Strategy: validation
Validate before calling
function isResolvable(name: string): boolean {
try { require.resolve(name); return true; } catch { return false; }
}
if (!isResolvable('@docusaurus/preset-classic')) {
throw new Error('Run: npm i @docusaurus/preset-classic');
} Try / catch
try {
const preset = resolveModuleName('classic', 'preset');
} catch (e) {
console.error('Preset not installed:', (e as Error).message);
throw e;
} Prevention
- Install all referenced presets/plugins/themes before `docusaurus start`.
- For local plugins, pass `require.resolve('./path')` rather than bare names.
- Run `pnpm install` after editing presets/plugins in config.
When it happens
Trigger: Referencing `presets: ['classic']`, `themes: ['live-codeblock']`, or `plugins: ['my-plugin']` when the corresponding npm package is not installed. The loop at moduleShorthand.ts:38-46 tries each pattern and the throw at :47-50 fires when `module` stays undefined.
Common situations: Forgetting to `npm install @docusaurus/preset-classic`; typo in the preset/plugin name; using a private/local plugin without the correct package name or path; monorepo package not built/linked.
Related errors
- Plugin "${pluginName}" is used ${pluginInstancesWithId.lengt
- Invalid route config: path must be a string and component is
- Route ${route.path} has conflicting props declared using bot
- A Docusaurus plugin returned 'undefined', which is forbidden
- A Docusaurus plugin is missing a 'name' property.\nNote that
AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12).
Data as JSON: /api/errors/eb29551813efb55a.
Report an issue: GitHub.