ruvnet/ruflo · error
No suitable models available for request
Error message
No suitable models available for request
What it means
Thrown by MultiModelRouter when routing a completion request (v3/@claude-flow/integration/src/multi-model-router.ts:518): after filtering candidates by required capabilities and scoring them, zero models remain. Either no registered model satisfies the request's constraints (context window, capabilities, budget, latency), or rule-based mode produced no matching rule and all candidates were filtered out.
Source
Thrown at v3/@claude-flow/integration/src/multi-model-router.ts:518
// Filter models by capabilities
let candidateModels = this.filterByCapabilities(request.requiredCapabilities);
// Filter by health (exclude unhealthy providers)
candidateModels = this.filterByHealth(candidateModels);
// Apply routing rules if in rule-based mode
if (this.config.mode === 'rule-based') {
const ruleResult = this.applyRules(request, candidateModels);
if (ruleResult) {
return ruleResult;
}
}
// Score and rank candidates
const scoredCandidates = this.scoreModels(request, candidateModels);
if (scoredCandidates.length === 0) {
throw new Error('No suitable models available for request');
}
// Select best candidate
const best = scoredCandidates[0];
const model = this.models.get(best.modelId)!;
const result: RoutingResult = {
provider: model.provider,
model: model.id,
reason: this.generateReason(best),
estimatedCost: best.estimatedCost,
estimatedLatency: model.latencyMs,
qualityScore: model.qualityScore,
alternatives: scoredCandidates.slice(1, 4).map(c => ({
provider: this.models.get(c.modelId)!.provider,
model: c.modelId,
estimatedCost: c.estimatedCost,
})),View on GitHub (pinned to fa13ee4ad6)
Solutions
- Inspect the request's constraints (requiredCapabilities, contextWindow, maxCost, maxLatency) and relax the one that eliminates all candidates.
- Register at least one model that satisfies the hard requirements — verify each model's capability flags in the registry.
- If in rule-based mode, add a catch-all rule so unmatched requests still get a default model instead of falling through to scoring with an empty set.
- Check that model registration succeeded (log this.models.size) — a silent provider init failure leaves the router empty.
Example fix
// before
const res = await router.route(request); // request requires tools, no model supports them
// after
const capable = [...router.models.values()].filter((m) => m.supportsTools);
if (capable.length === 0) throw new Error('register a tool-capable model first');
const res = await router.route({ ...request, requiredCapabilities: { supportsTools: true } }); Defensive patterns
Strategy: fallback
Validate before calling
const capable = [...router.models.values()].filter((m) =>
m.capabilities.supportsTools || !request.tools
);
if (capable.length === 0) {
// drop optional constraints or register a capable model before routing
request = { ...request, tools: undefined };
} Type guard
function requestIsSatisfiable(models: Model[], req: LLMRequest): boolean {
return models.some((m) =>
(!req.tools || m.supportsTools) &&
(!req.responseFormat || req.responseFormat !== 'json' || m.supportsJson) &&
m.contextWindow >= estimateTokens(req)
);
} Try / catch
try {
return await router.complete(request);
} catch (e) {
if ((e as Error).message === 'No suitable models available for request') {
return router.complete(relaxConstraints(request)); // drop maxCost/latency or capability extras
}
throw e;
} Prevention
- Keep at least one high-capability model registered as a catch-all.
- Validate capability requirements against the registry at startup, not at request time.
- Add a default routing rule in rule-based mode so unmatched requests never reach empty scoring.
When it happens
Trigger: Requesting tools support when every registered model has supportsTools: false; asking for a context window larger than any model's; a maxCost/maxLatency budget that filters out all providers; an empty or failed model registration (no models in this.models); responseFormat 'json' when no model supports JSON mode.
Common situations: Only a cheap/legacy provider registered while the request needs tool calling; budget env vars set too aggressively (MAX_COST_PER_REQUEST=0); model registry misconfigured after provider outages removed models; capability metadata stale after an SDK upgrade.
Related errors
- Unknown template preset: ${template}. Use: ${Object.keys(pre
- Unknown role: ${m.role}
- OpenAI embedding failed: ${message}
- Circuit breaker open for provider: ${provider}
- No available providers
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/6425c137a67f9f92.
Report an issue: GitHub.