ruvnet/ruflo · critical

Plugin initialization failed: ${initErrors.join(' ')}

Error message

Plugin initialization failed:
${initErrors.join('
')}

What it means

Thrown at the end of EnhancedPluginRegistry.initialize() when any plugin's init recorded an error. Initialization runs by strategy (sequential, parallel, parallel-safe) and captures per-plugin failures into each entry's error field instead of throwing immediately; afterwards initialize() collects every 'pluginName: error' pair and throws this aggregate, so one or more plugin init failures abort the whole registry initialization (initialized stays false).

Source

Thrown at v3/@claude-flow/plugins/src/registry/enhanced-plugin-registry.ts:423

    switch (strategy) {
      case 'sequential':
        await this.initializeSequential();
        break;
      case 'parallel':
        await this.initializeParallel();
        break;
      case 'parallel-safe':
        await this.initializeParallelSafe();
        break;
    }

    // Check for initialization errors (including conflicts)
    const initErrors = Array.from(this.plugins.values())
      .filter(e => e.error)
      .map(e => `${e.plugin.metadata.name}: ${e.error}`);

    if (initErrors.length > 0) {
      throw new Error(`Plugin initialization failed:\n${initErrors.join('\n')}`);
    }

    this.initialized = true;
    this.logger.info(`Registry initialized with ${this.plugins.size} plugins (${strategy})`);
  }

  private async initializeSequential(): Promise<void> {
    const loadOrder = this.dependencyGraph.getLoadOrder();

    for (const name of loadOrder) {
      const entry = this.plugins.get(name);
      if (!entry) continue;

      if (!entry.config.enabled) {
        this.logger.info(`Plugin ${name} is disabled, skipping initialization`);
        continue;
      }

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Parse each line of the aggregate message to find which plugin(s) failed and why; fix that plugin's init problem (config, credentials, connectivity)
  2. Make the failing plugin's init resilient (retry, defaults, or graceful degradation) so a single plugin cannot abort registry startup
  3. For name-collision errors, change the registry's conflict resolution strategy away from 'error' or rename the conflicting extension
  4. If the plugin is non-essential, unregister it (or register it later) so initialize() can succeed without it

Example fix

// before
await registry.initialize();
// throws: Plugin initialization failed:
//   db-plugin: connect ECONNREFUSED localhost:5432

// after - make the plugin's init non-fatal:
async init(ctx) {
  try {
    await this.client.connect();
  } catch (err) {
    ctx.logger.warn('db-plugin degraded:', err.message);
    this.degraded = true; // init() still resolves
  }
}
await registry.initialize(); // succeeds, db-plugin degraded
Defensive patterns

Strategy: try-catch

Validate before calling

// Optional dry run: surface failing init early per-plugin instead of aborting the registry
for (const plugin of pluginsToLoad) {
  try {
    await plugin.init?.({ logger }); // minimal context
  } catch (err) {
    logger.warn(`plugin ${plugin.metadata.name} init will fail: ${(err as Error).message}`);
  }
}

Try / catch

try {
  await registry.initialize();
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Plugin initialization failed')) {
    const failed = err.message.split('\n').slice(1); // 'name: cause' lines
    for (const line of failed) logger.error(`init failure: ${line}`);
    // option: unregister failing plugins and retry initialize() on a fresh registry
  }
  throw err;
}

Prevention

When it happens

Trigger: A plugin's init() rejecting (bad config, missing API key, unreachable service) during initialize(); initialization conflicts recorded as errors (e.g. extension name collisions under the 'error' resolution strategy); a plugin timing out within its init and recording an error; any strategy (sequential/parallel/parallel-safe) since all funnel through the same post-check.

Common situations: External-service plugins (DB, LLM) whose init fails from missing env vars/credentials in the deployed environment; order-dependent plugins initializing in parallel and conflicting; one broken third-party plugin blocking the entire app boot; transient network failure during init treated as fatal.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/8df03bbe9d3147f8. Report an issue: GitHub.