facebook/docusaurus · error · Error

Theme ${themeName} not found

Error message

Theme ${themeName} not found

What it means

Thrown by `getPluginByThemeName(plugins, themeName)` when no loaded plugin's computed theme name matches the requested `themeName`. This is the lookup that powers every swizzle command — it must resolve a plugin before any component work begins.

Source

Thrown at packages/docusaurus/src/commands/swizzle/themes.ts:30

import {askThemeName} from './prompts';
import {findStringIgnoringCase, type SwizzlePlugin} from './common';

export function pluginToThemeName(plugin: SwizzlePlugin): string | undefined {
  if (plugin.instance.getThemePath) {
    return (
      (plugin.instance.version as {name?: string}).name ?? plugin.instance.name
    );
  }
  return undefined;
}

export function getPluginByThemeName(
  plugins: SwizzlePlugin[],
  themeName: string,
): SwizzlePlugin {
  const plugin = plugins.find((p) => pluginToThemeName(p) === themeName);
  if (!plugin) {
    throw new Error(`Theme ${themeName} not found`);
  }
  return plugin;
}

export function getThemeNames(plugins: SwizzlePlugin[]): string[] {
  const themeNames = _.uniq(
    // The fact that getThemePath is attached to the plugin instance makes
    // this code impossible to optimize. If this is a static method, we don't
    // need to initialize all plugins just to filter which are themes
    // Benchmark: loadContext-58ms; initPlugins-323ms
    plugins.map((plugin) => pluginToThemeName(plugin)).filter(Boolean),
  ) as string[];

  // Opinionated ordering: user is most likely to swizzle:
  // - the classic theme
  // - official themes
  // - official plugins
  return _.orderBy(

View on GitHub (pinned to 3f483e80e3)

Solutions

  1. List available themes: `docusaurus swizzle --list` and copy the exact theme name.
  2. Install the theme: `pnpm add <theme-package>` and add it to your config's `themes`/`presets`.
  3. If it is a custom theme, ensure the plugin's `getThemePath()` returns a non-empty string so it is recognized as a theme.
  4. Match the theme name exactly (case-sensitive, including the npm scope).

Example fix

// before (docusaurus.config.js)
export default { presets: [] }; // no theme registered
// after
export default {
  presets: [['classic', {}]],
};
Defensive patterns

Strategy: validation

Validate before calling

const themeNames = getThemeNames(plugins);
if (!themeNames.includes(themeName)) {
  throw new Error(`Unknown theme ${themeName}. Available: ${themeNames.join(', ')}`);
}

Type guard

function isKnownTheme(name: string, names: string[]): name is string {
  return names.includes(name);
}

Try / catch

try { await getPluginByThemeName(plugins, themeName); }
catch (e) {
  if (/Theme .* not found/.test(e.message)) {
    console.error(`Run: docusaurus swizzle --list`); process.exit(1);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `docusaurus swizzle <themeName> ...` (or the internal lookup) where `<themeName>` is not among the theme names produced by the currently loaded plugins. Causes: typo, theme not installed, theme plugin not registered in config.

Common situations: Typing `@docusaurus/classic-theme` instead of `@docusaurus/theme-classic`; forgetting to add the theme to `plugins`/presets in `docusaurus.config.js`; theme package installed but its `getThemePath` returns nothing; package not yet installed in node_modules.

Related errors


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