{"record":{"id":"7e8556500f739142","repo":"ruvnet/ruflo","slug":"plugin-this-metadata-name-already-initialized","errorCode":null,"errorMessage":"Plugin ${this.metadata.name} already initialized","messagePattern":"Plugin (.+?) already initialized","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/plugins/src/core/base-plugin.ts","lineNumber":146,"sourceCode":"  protected get services(): ServiceContainer {\n    return this.context.services;\n  }\n\n  protected get settings(): Record<string, unknown> {\n    return this.config.settings;\n  }\n\n  // =========================================================================\n  // Lifecycle Implementation\n  // =========================================================================\n\n  /**\n   * Initialize the plugin.\n   * Subclasses should override onInitialize() instead of this method.\n   */\n  async initialize(context: PluginContext): Promise<void> {\n    if (this._state !== 'uninitialized') {\n      throw new Error(`Plugin ${this.metadata.name} already initialized`);\n    }\n\n    this.setState('initializing');\n    this._context = context;\n    this._initTime = new Date();\n\n    try {\n      // Validate dependencies\n      await this.validateDependencies();\n\n      // Validate configuration\n      await this.validateConfig();\n\n      // Call subclass initialization\n      await this.onInitialize();\n\n      this.setState('initialized');\n      this.eventBus.emit(PLUGIN_EVENTS.INITIALIZED, { plugin: this.metadata.name });","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/plugins/src/core/base-plugin.ts#L128-L164","documentation":"initialize() only accepts plugins in the 'uninitialized' state; any second call throws 'already initialized'. The state flips to 'initializing' immediately upon entry, before validation runs, so even retrying a failed initialize() on the same instance is rejected. This is a strict one-shot lifecycle machine, not an idempotent init.","triggerScenarios":"Calling plugin.initialize() or registry.initialize() twice on the same plugin instance; retry wrappers that re-run initialize after a transient failure; dev-mode double-mounting (React StrictMode effects, HMR) that executes setup code twice; registering one shared plugin object with two registries.","commonSituations":"Fire-and-forget init plus an explicit init elsewhere in boot code; retry-on-error logic around initialization; module singletons surviving hot reloads while init code re-runs.","solutions":["Check the plugin's state before initializing and skip when it is not 'uninitialized'","Create a fresh plugin instance for each initialization instead of reusing one (rebuild the plugin factory result)","Wrap init in a once() memoization at the call site so repeated invocations share the first promise"],"exampleFix":"// before\nawait plugin.initialize(ctx); // ...later, somewhere else:\nawait plugin.initialize(ctx); // Error: already initialized\n\n// after\nconst initPlugin = once(() => plugin.initialize(ctx));\nawait initPlugin(); // first call wins; later calls are no-ops","handlingStrategy":"validation","validationCode":"import once from 'lodash/once'; // or a hand-rolled memo\nconst initPlugin = once(() => plugin.initialize(context));\nawait initPlugin(); // safe to call from every boot path\n\n// explicit state check when once() is not available:\nif (plugin.state === 'uninitialized') {\n  await plugin.initialize(context);\n}","typeGuard":"type Initializable = { state?: string };\nfunction canInitialize(p: Initializable): boolean {\n  return p.state === 'uninitialized';\n}","tryCatchPattern":null,"preventionTips":["Initialize each plugin exactly once; funnel all init paths through one function","Create a fresh instance (via the plugin factory) when a re-init is genuinely needed","Guard dev-mode double-mounts (StrictMode/HMR) with once() wrappers"],"tags":["plugin","lifecycle","double-initialization","state-machine"],"backgroundTag":"already-initialized","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}