ruvnet/ruflo · error
Provider ${name} already registered
Error message
Provider ${name} already registered What it means
Thrown by LLMProviderRegistry.register() when a provider whose definition.name is already present in the providers Map is registered a second time. The registry keys providers strictly by name, so duplicate names are treated as a programming/setup error rather than an overwrite.
Source
Thrown at v3/@claude-flow/plugins/src/providers/index.ts:136
costOptimization: false,
retryConfig: {
maxRetries: 3,
initialDelayMs: 1000,
maxDelayMs: 30000,
backoffMultiplier: 2,
},
...config,
};
}
/**
* Register a provider.
*/
register(provider: ILLMProvider): void {
const name = provider.definition.name;
if (this.providers.has(name)) {
throw new Error(`Provider ${name} already registered`);
}
const entry: ProviderEntry = {
provider,
registeredAt: new Date(),
requestCount: 0,
errorCount: 0,
totalTokensUsed: 0,
totalCost: 0,
};
this.providers.set(name, entry);
this.latencyTracking.set(name, []);
this.emit(PROVIDER_EVENTS.REGISTERED, { provider: name });
}
/**
* Unregister a provider.View on GitHub (pinned to fa13ee4ad6)
Solutions
- Call registry.unregister(name) (or build a fresh registry) before re-registering the same provider name
- Guard registration with registry.get(name) - skip if the provider is already present
- Give custom or wrapped providers a unique definition.name instead of shadowing a built-in name
Example fix
// before
registry.register(openaiProvider);
registry.register(customOpenai); // definition.name === 'openai' -> throws
// after
if (!registry.get('openai')) {
registry.register(openaiProvider);
} else {
registry.unregister('openai');
registry.register(customOpenai);
} Defensive patterns
Strategy: validation
Validate before calling
if (registry.get(provider.definition.name)) {
registry.unregister(provider.definition.name);
}
registry.register(provider); Try / catch
try {
registry.register(provider);
} catch (err) {
if (err instanceof Error && err.message.endsWith('already registered')) {
return; // idempotent setup: keep the existing registration
}
throw err;
} Prevention
- Make registration idempotent: check registry.get(name) before register()
- Derive every lookup from provider.definition.name, never a hand-typed string
- In tests, use a fresh registry per case instead of a shared singleton that accumulates registrations
When it happens
Trigger: Calling registry.register(provider) twice with two ILLMProvider instances whose definition.name is identical (e.g. two 'openai' wrappers); hot-reload or repeated module import re-running setup code that registers the same provider; registering a custom provider that reuses a well-known name like 'anthropic'.
Common situations: Test suites that build a fresh registry per test but share a module-level provider list; HMR or watch-mode re-executing initialization; wrapping a stock provider under the same name instead of a distinct one; duplicate register calls left behind after a refactor.
Related errors
- No available provider for model ${request.model}
- Provider ${providerName} not found
- Plugin ${name} already registered
- LocalTransport: unreachable peer ${to}
- Can only resume paused agent
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/4ce09743097fe058.
Report an issue: GitHub.