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

  1. Inspect the request's constraints (requiredCapabilities, contextWindow, maxCost, maxLatency) and relax the one that eliminates all candidates.
  2. Register at least one model that satisfies the hard requirements — verify each model's capability flags in the registry.
  3. 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.
  4. 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

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


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