ruvnet/ruflo · error

Unknown provider: ${config.provider}

Error message

Unknown provider: ${config.provider}

What it means

ProviderManager.createProvider() switches on config.provider and only recognizes 'anthropic', 'openai', 'google', 'cohere', 'ollama' and 'ruvector'; every other value falls through to a default that throws a plain Error. The comparison is case-sensitive.

Source

Thrown at v3/@claude-flow/providers/src/provider-manager.ts:131

      config,
      logger: this.logger,
    };

    switch (config.provider) {
      case 'anthropic':
        return new AnthropicProvider(options);
      case 'openai':
        return new OpenAIProvider(options);
      case 'google':
        return new GoogleProvider(options);
      case 'cohere':
        return new CohereProvider(options);
      case 'ollama':
        return new OllamaProvider(options);
      case 'ruvector':
        return new RuVectorProvider(options);
      default:
        throw new Error(`Unknown provider: ${config.provider}`);
    }
  }

  /**
   * Complete a request with automatic provider selection
   */
  async complete(request: LLMRequest, preferredProvider?: LLMProvider): Promise<LLMResponse> {
    // Check cache first
    if (this.config.cache?.enabled) {
      const cached = this.getCached(request);
      if (cached) {
        this.logger.debug('Cache hit', { requestId: request.requestId });
        return cached;
      }
    }

    // Select provider
    const provider = preferredProvider

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Use one of the exact case-sensitive ids: anthropic | openai | google | cohere | ollama | ruvector
  2. Normalize the value at config load: trim() + toLowerCase() before it reaches the manager
  3. After initialize(), check manager.getProvider(id) returned a provider - initialization failures are logged, not thrown, so a typo silently yields a missing provider
  4. For unsupported vendors, instantiate the provider class yourself and pass it as preferredProvider to manager.complete()

Example fix

// before
providers: [{ provider: 'OpenAI' as any, apiKey, model: 'gpt-4o' }] // capital O -> Unknown provider

// after
providers: [{ provider: 'openai', apiKey, model: 'gpt-4o' }] // exact registry id
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED_PROVIDERS = ['anthropic', 'openai', 'google', 'cohere', 'ollama', 'ruvector'] as const;

for (const p of managerConfig.providers) {
  if (!SUPPORTED_PROVIDERS.includes(p.provider as never)) {
    throw new Error(
      `Unsupported provider '${p.provider}'. Supported: ${SUPPORTED_PROVIDERS.join(', ')}`
    );
  }
}
await manager.initialize();

Type guard

const SUPPORTED_PROVIDERS = ['anthropic', 'openai', 'google', 'cohere', 'ollama', 'ruvector'] as const;
type SupportedProviderId = (typeof SUPPORTED_PROVIDERS)[number];

function isSupportedProvider(v: unknown): v is SupportedProviderId {
  return typeof v === 'string' && (SUPPORTED_PROVIDERS as readonly string[]).includes(v.trim().toLowerCase())
    ? true
    : false;
}

Prevention

When it happens

Trigger: A ProviderManagerConfig whose providers[] entry has provider: 'azure-openai', 'groq', 'mistral', 'bedrock', or a case variant like 'OpenAI' - initialize() then fails (the manager logs 'Failed to initialize ...' and skips that provider, leaving it absent from the registry).

Common situations: Provider id from an env var with different casing/whitespace; config authored for a newer version supporting more vendors; copy-pasted example using an alias; trailing whitespace after JSON/YAML edit.

Related errors


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