ruvnet/ruflo · error
No available provider for model ${request.model}
Error message
No available provider for model ${request.model} What it means
Thrown by LLMProviderRegistry.execute() when getBest({ model }) returns undefined. getBest filters registered providers by model support (definition.models must include the requested model), then drops any provider whose getRateLimitStatus().isLimited is true; if both filters remove every candidate, execute() has nothing to run on and throws.
Source
Thrown at v3/@claude-flow/plugins/src/providers/index.ts:231
// Sort by success rate
candidates.sort((a, b) => {
const rateA = a.requestCount > 0 ? (a.requestCount - a.errorCount) / a.requestCount : 1;
const rateB = b.requestCount > 0 ? (b.requestCount - b.errorCount) / b.requestCount : 1;
return rateB - rateA;
});
}
return candidates[0]?.provider;
}
/**
* 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;
View on GitHub (pinned to fa13ee4ad6)
Solutions
- Check with registry.getBest({ model }) (non-throwing) before execute(), or catch and inspect the registry's provider list to see which models are actually advertised
- Add the requested model to the provider's definition.models array (or fix the typo) so the model filter matches
- Wait for or reset rate-limit windows: providers excluded via getRateLimitStatus().isLimited become eligible again once the window clears
- Register a fallback provider that supports the model so one limited provider does not empty the candidate set
Example fix
// before
const res = await registry.execute({ model: 'gpt-4o-mini', messages });
// throws if no provider advertises that model
// after
if (!registry.getBest({ model: 'gpt-4o-mini' })) {
throw new Error(
`no provider for gpt-4o-mini; available models: ${
registry.listProviders().map(p => p.definition.models.join(',')).join('; ')
}`
);
}
const res = await registry.execute({ model: 'gpt-4o-mini', messages }); Defensive patterns
Strategy: fallback
Validate before calling
if (!registry.getBest({ model: request.model })) {
const available = registry.listProviders()
.flatMap(p => p.definition.models)
.join(', ');
throw new Error(`model ${request.model} has no provider; available models: ${available}`);
} Type guard
function hasProviderForModel(
registry: { getBest(o?: { model?: string }): unknown },
model: string
): boolean {
return registry.getBest({ model }) !== undefined;
} Try / catch
try {
return await registry.execute(request);
} catch (err) {
if (err instanceof Error && err.message.startsWith('No available provider')) {
// fall back to a model that IS registered
return registry.execute({ ...request, model: FALLBACK_MODEL });
}
throw err;
} Prevention
- Boot-fail fast: assert getBest() for every model your app will request right after registering providers
- Keep definition.models arrays in sync when adopting new model names
- Register at least two providers per critical model so rate-limiting one does not empty the pool
- Surface provider/model inventory in health checks to catch drift before requests do
When it happens
Trigger: Calling execute({ model: 'gpt-4o', ... }) when no registered provider lists 'gpt-4o' in definition.models; every provider that supports the model is currently rate-limited (isLimited true); executing before any provider was registered; typo in the model string (case or suffix mismatch against definition.models).
Common situations: New model name deployed in the app before the provider definition was updated; all providers supporting the model hitting 429s so the rate-limit filter empties the candidate list; registering a provider with a narrow models array and then requesting a variant (e.g. 'gpt-4o-mini' not listed); tests that execute against an empty registry.
Related errors
- Provider ${name} already registered
- Provider ${providerName} not found
- LocalTransport: unreachable peer ${to}
- Can only resume paused agent
- Only the original claimant can contest the steal
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/3789a2185a319b2b.
Report an issue: GitHub.