nocobase/nocobase · critical

plugin [${options?.name || 'unknown'}] load error

Error message

plugin [${options?.name || 'unknown'}] load error

What it means

After resolving the plugin's package to a class via PluginManager.resolvePlugin(), addOrThrow() throws when the resolver returns a falsy value — i.e. the plugin module could not be resolved/loaded. The message includes the plugin name (or 'unknown' if no name was determined).

Source

Thrown at packages/core/server/src/plugin-manager/plugin-manager.ts:355

    if (!options.name && typeof plugin === 'string') {
      options.name = plugin;
    }
    if (typeof plugin === 'string' && options.name && !options.packageName) {
      const packageName = await PluginManager.getPackageName(options.name);
      if (packageName) {
        options['packageName'] = packageName;
      }
    }
    if (options.packageName) {
      const packageJson = await PluginManager.getPackageJson(options.packageName);
      options['packageJson'] = packageJson;
      options['version'] = packageJson.version;
    }

    const P = await PluginManager.resolvePlugin(options.packageName || plugin, isUpgrade, !!options.packageName);

    if (!P) {
      throw new Error(`plugin [${options?.name || 'unknown'}] load error`);
    }

    const instance: Plugin = new P(createAppProxy(this.app), options);

    this.pluginInstances.set(P, instance);
    if (options.name) {
      this.pluginAliases.set(options.name, instance);
    }
    if (options.packageName) {
      this.pluginAliases.set(options.packageName, instance);
    }
    await instance.afterAdd();
  }

  async add(plugin?: string | typeof Plugin, options: any = {}, insert = false, isUpgrade = false) {
    try {
      await this.addOrThrow(plugin, options, insert, isUpgrade);
    } catch (error) {

View on GitHub (pinned to fa42722fef)

Solutions

  1. Run yarn/npm install so the plugin package exists in node_modules
  2. Verify the plugin name/packageName spelling matches the actual package (@nocobase/plugin-xxx)
  3. Check the package's main/module/exports fields point at a buildable/compiled entry
  4. Rebuild the plugin (yarn build) if it is a local/custom plugin
  5. Enable logs or call PluginManager.resolvePlugin(name) manually to see why resolution returns null

Example fix

// before
await app.pm.add('plugin-missing'); // load error
// after
yarn add @nocobase/plugin-missing
await app.pm.add('plugin-missing');
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'fs';
function pluginPackageExists(name: string): boolean {
  const candidates = [`node_modules/@nocobase/plugin-${name}`, `node_modules/${name}`];
  return candidates.some((p) => fs.existsSync(p));
}
if (!pluginPackageExists('users')) throw new Error('run yarn install first');

Type guard

function isResolvablePluginClass(P: unknown): P is typeof Plugin {
  return typeof P === 'function' && P.prototype instanceof Plugin;
}

Try / catch

try {
  await app.pm.add('users');
} catch (e) {
  if (e.message.includes('load error')) {
    console.error('Plugin package missing or broken; run yarn install / yarn build');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling add/enable with a plugin name whose npm package is not installed in node_modules; a broken package.json/exports that the resolver cannot load; passing an invalid packageName option; dependency not installed after adding to package.json without yarn install.

Common situations: Deploying code that references a plugin not in package.json; a custom plugin built to the wrong dist path; npm/yarn install failed silently; plugin name typo mismatching the exported package; version upgrade removed the package.

Related errors


AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01). Data as JSON: /api/errors/9d466e7aebcfdaac. Report an issue: GitHub.