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
- Enumerate the collection's plugin names from the loaded manifest and use the exact string
- Ensure the collection was loaded successfully before enable/disable calls
- 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
- Source plugin names from collection manifest constants, not free text
- Verify collection load success before enable/disable calls
- Pin collection versions and re-validate names on upgrade
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
- Collection ${collectionId} not found
- Collection ${collection.id} already loaded
- Cannot disable ${pluginName}: other plugins may depend on it
- Pool ${this.id} at maximum capacity (${this.config.maxWorker
- Invalid completion type
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/d23ce6e8a1d26948.
Report an issue: GitHub.