{"record":{"id":"06b9912d43182893","repo":"ruvnet/ruflo","slug":"duplicate-plugin","errorCode":"DUPLICATE_PLUGIN","errorMessage":"Plugin '${plugin.name}' is already loaded","messagePattern":"Plugin '(.+?)' is already loaded","errorType":"exception","errorClass":"PluginError","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/shared/src/plugin-loader.ts","lineNumber":99,"sourceCode":"  private registry: PluginRegistry;\n  private initializationOrder: string[] = [];\n  private healthCheckIntervalId?: NodeJS.Timeout;\n\n  constructor(registry: PluginRegistry, config?: PluginLoaderConfig) {\n    this.registry = registry;\n    this.config = { ...DEFAULT_CONFIG, ...config };\n  }\n\n  /**\n   * Load a single plugin\n   */\n  async loadPlugin(plugin: ClaudeFlowPlugin, context: PluginContext): Promise<void> {\n    // Validate plugin\n    this.validatePlugin(plugin);\n\n    // Check for duplicates\n    if (this.registry.hasPlugin(plugin.name)) {\n      throw new PluginError(\n        `Plugin '${plugin.name}' is already loaded`,\n        plugin.name,\n        'DUPLICATE_PLUGIN'\n      );\n    }\n\n    // Register plugin in uninitialized state\n    this.registry.registerPlugin(plugin, 'uninitialized', context);\n\n    // Resolve dependencies\n    if (this.config.strictDependencies) {\n      this.validateDependencies(plugin);\n    }\n\n    // Initialize plugin\n    await this.initializePlugin(plugin, context);\n\n    // Update initialization order","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/shared/src/plugin-loader.ts#L81-L117","documentation":"PluginLoader.loadPlugin(plugin, context) first validates the plugin interface, then registers it by unique name; if the registry already has a plugin with the same name it throws PluginError with code 'DUPLICATE_PLUGIN' before any initialization runs (PluginError carries pluginName and code fields). Loading the same plugin object - or a different object with the same name - twice on one loader is rejected.","triggerScenarios":"loadPlugins([p, p]) with the same plugin listed twice; two entries registering 'my-plugin' (a local copy and an npm copy); calling loadPlugin again in retry code after a partial success; HMR re-running the registration module with the same plugin definitions.","commonSituations":"Monorepos bundling the same plugin twice; re-entrant init code; plugin name collisions between teams; tests reusing a loader across cases.","solutions":["Deduplicate the list by name before loading: [...new Map(plugins.map(p => [p.name, p])).values()]","Make plugin loading single-shot by memoizing the loadPlugins call","If overlap is expected, catch PluginError with code 'DUPLICATE_PLUGIN' and treat that specific plugin as already-loaded success"],"exampleFix":"// before\nawait loader.loadPlugins([authPlugin, authPlugin]); // second entry throws\n\n// after\nconst unique = [...new Map(plugins.map(p => [p.name, p])).values()];\nawait loader.loadPlugins(unique);","handlingStrategy":"validation","validationCode":"// dedupe by name before loading - registry keys are plugin names\nconst uniquePlugins = [...new Map(plugins.map(p => [p.name, p])).values()];\nawait loader.loadPlugins(uniquePlugins);","typeGuard":null,"tryCatchPattern":"import { PluginError } from '@claude-flow/shared/dist/plugin-interface';\ntry {\n  await loader.loadPlugin(plugin, ctx);\n} catch (e) {\n  if (e instanceof PluginError && e.code === 'DUPLICATE_PLUGIN') {\n    return; // same plugin already registered - treat as idempotent\n  }\n  throw e;\n}","preventionTips":["Deduplicate plugin lists by name before loadPlugins","Memoize the loadPlugins call so init code cannot run twice","Use PluginError.code (not message parsing) to branch on plugin-load failures"],"tags":["plugins","loader","duplicate","registry","initialization"],"backgroundTag":"duplicate-plugin-registration","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"}