ruvnet/ruflo · error

Registry already initialized

Error message

Registry already initialized

What it means

Thrown by EnhancedPluginRegistry.initialize() when called on a registry whose initialized flag is already true. The flag is set at the end of a successful initialize(), so this error fires on any second initialize() call - including well-meant retries after a first call that succeeded.

Source

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

    }

    // Shutdown and remove
    await this.shutdownPlugin(name);
    this.removePluginFromGraph(name);

    this.logger.info(`Plugin unregistered: ${name}`);
  }

  // =========================================================================
  // Initialization
  // =========================================================================

  /**
   * Initialize all registered plugins.
   */
  async initialize(): Promise<void> {
    if (this.initialized) {
      throw new Error('Registry already initialized');
    }

    // Validate dependencies
    const errors = this.dependencyGraph.validate();
    const criticalErrors = errors.filter(e => e.type !== 'missing' || !this.isOptionalDependency(e));

    if (criticalErrors.length > 0) {
      const errorMessages = criticalErrors.map(e => e.message).join('\n');
      throw new Error(`Dependency validation failed:\n${errorMessages}`);
    }

    // Initialize based on strategy
    const strategy = this.config.initializationStrategy ?? 'sequential';

    switch (strategy) {
      case 'sequential':
        await this.initializeSequential();
        break;

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Call initialize() exactly once per registry instance; guard boot code with a check of the registry's initialized state if exposed
  2. For re-init after a bad state, create a new registry and re-register plugins rather than re-initializing the spent one
  3. Move initialize() out of helper/retry functions into a single bootstrap point

Example fix

// before
async function boot() {
  await registry.initialize();
}
await boot();
await boot(); // second call -> Registry already initialized

// after
let booted = false;
async function boot() {
  if (booted) return;
  await registry.initialize();
  booted = true;
}
Defensive patterns

Strategy: validation

Validate before calling

if (!isRegistryInitialized(registry)) {
  await registry.initialize();
} else {
  logger.debug('registry already initialized; skipping');
}

Type guard

function isRegistryInitialized(
  registry: object
): boolean {
  const r = registry as Record<string, unknown>;
  if (typeof r['isInitialized'] === 'function') {
    return (r['isInitialized'] as () => boolean)();
  }
  return r['initialized'] === true;
}

Try / catch

try {
  await registry.initialize();
} catch (err) {
  if (err instanceof Error && err.message === 'Registry already initialized') {
    return; // idempotent bootstrap
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling initialize() in both an init hook and main() so it runs twice; a re-initialize-on-failure loop calling initialize() again after the first call already set initialized=true; sharing a module-level registry across tests that each call initialize().

Common situations: Framework lifecycle calling setup more than once (e.g. dev server restart in-process); tests reusing a singleton registry; orchestrator code that retries the whole boot step including initialize().

Related errors


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