ruvnet/ruflo · error

Provider ${providerName} not found

Error message

Provider ${providerName} not found

What it means

Thrown by LLMProviderRegistry.executeWithProvider() when providers.get(providerName) misses. This is a plain Map lookup on the registered names, so it fires only when the name is genuinely unknown to this registry instance (never registered, unregistered, or a name mismatch).

Source

Thrown at v3/@claude-flow/plugins/src/providers/index.ts:243

   * Execute a request with automatic provider selection and fallback.
   */
  async execute(request: LLMRequest): Promise<LLMResponse> {
    const provider = this.getBest({ model: request.model });

    if (!provider) {
      throw new Error(`No available provider for model ${request.model}`);
    }

    return this.executeWithProvider(provider.definition.name, request);
  }

  /**
   * Execute a request on a specific provider with retry.
   */
  async executeWithProvider(providerName: string, request: LLMRequest): Promise<LLMResponse> {
    const entry = this.providers.get(providerName);
    if (!entry) {
      throw new Error(`Provider ${providerName} not found`);
    }

    const retryConfig = this.config.retryConfig!;
    let lastError: Error | null = null;
    let delay = retryConfig.initialDelayMs;

    for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {
      if (attempt > 0) {
        await this.delay(delay);
        delay = Math.min(delay * retryConfig.backoffMultiplier, retryConfig.maxDelayMs);
      }

      try {
        this.emit(PROVIDER_EVENTS.REQUEST_START, {
          provider: providerName,
          model: request.model,
          attempt,
        });

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Check registry.get(providerName) first and use the exact definition.name it returns
  2. If the provider was unregistered intentionally, re-register it or route requests to a live name
  3. Centralize provider names in exported constants shared by registration and call sites

Example fix

// before
await registry.executeWithProvider('open-ai', request); // typo -> throws

// after
const name = openaiProvider.definition.name; // 'openai'
if (!registry.get(name)) await registry.register(openaiProvider);
await registry.executeWithProvider(name, request);
Defensive patterns

Strategy: validation

Validate before calling

const provider = registry.get(providerName);
if (!provider) {
  throw new Error(
    `unknown provider '${providerName}'; registered: ${
      registry.listProviders().map(p => p.definition.name).join(', ')
    }`
  );
}
await registry.executeWithProvider(providerName, request);

Try / catch

try {
  await registry.executeWithProvider(name, request);
} catch (err) {
  if (err instanceof Error && err.message.endsWith('not found')) {
    await registry.register(requiredProvider); // lazy (re-)register, then retry once
    return registry.executeWithProvider(name, request);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling executeWithProvider('openai', request) when only e.g. 'anthropic' was registered; using a name that differs from the provider's definition.name (typo, casing, 'open-ai' vs 'openai'); calling after unregister(name) removed the entry; calling on a different registry instance than the one the provider was registered on.

Common situations: Name constants drifting between definition.name and call sites; multiple registries (one per environment/test) and the provider registered on the wrong one; unregister during shutdown racing in-flight requests.

Related errors


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