ruvnet/ruflo · error · Error

Plugin ${pluginName} not found in collection ${collectionId}

Error message

Plugin ${pluginName} not found in collection ${collectionId}

What it means

enablePlugin resolves the (collectionId, pluginName) pair through findResolvedEntry against the entries resolved at loadCollection time; a miss — the name is not part of that collection, the collection was never loaded (nothing resolved), or a casing/typo mismatch — is rejected before any override or registration happens.

Source

Thrown at v3/@claude-flow/plugins/src/collections/collection-manager.ts:202

  /**
   * Get a collection by ID.
   */
  getCollection(id: string): PluginCollection | undefined {
    return this.collections.get(id);
  }

  // =========================================================================
  // Plugin Activation
  // =========================================================================

  /**
   * Enable a plugin from a collection.
   */
  async enablePlugin(collectionId: string, pluginName: string): Promise<void> {
    const resolved = this.findResolvedEntry(collectionId, pluginName);
    if (!resolved) {
      throw new Error(`Plugin ${pluginName} not found in collection ${collectionId}`);
    }

    // Remove from disabled, add to enabled
    this.disabledOverrides.get(collectionId)?.delete(pluginName);
    this.enabledOverrides.get(collectionId)?.add(pluginName);

    // Register if not already registered
    if (!this.registry.getPlugin(pluginName)) {
      await this.registerResolvedPlugin(resolved.plugin, resolved.entry);
    }
  }

  /**
   * Disable a plugin from a collection.
   */
  async disablePlugin(collectionId: string, pluginName: string): Promise<void> {
    const resolved = this.findResolvedEntry(collectionId, pluginName);
    if (!resolved) {

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Enumerate the collection's plugin names from the loaded manifest and use the exact string
  2. Ensure the collection was loaded successfully before enable/disable calls
  3. After upgrading a collection, re-check plugin names against its manifest

Example fix

// before
await manager.enablePlugin('analytics', 'telemetry-sink'); // name not in manifest -> throws

// after
const names = collection.plugins.map((e) => expectedPluginName(e));
if (!names.includes('telemetry-sink')) {
  throw new Error(`collection provides: ${names.join(', ')}`);
}
await manager.enablePlugin('analytics', 'telemetry-sink');
Defensive patterns

Strategy: validation

Validate before calling

const known = new Set(collection.plugins.map((e) => expectedPluginName(e)));
if (!known.has(pluginName)) {
  throw new Error(`unknown plugin ${pluginName}; collection provides: ${[...known].join(', ')}`);
}
await manager.enablePlugin(collectionId, pluginName);

Try / catch

try {
  await manager.enablePlugin(collectionId, pluginName);
} catch (e) {
  if (e instanceof Error && e.message.includes('not found in collection')) {
    // re-derive names from the manifest and surface the available list
  } else throw e;
}

Prevention

When it happens

Trigger: Enabling a plugin name that is not in the loaded collection's manifest; calling enablePlugin before loadCollection for that collection; using a plugin name that was renamed in a newer collection version.

Common situations: Plugin renamed across versions while operator config keeps the old name; referencing a plugin that belongs to a different collection; enabling on a manager whose load failed so no entries resolved.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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