decolua/9router · error
Model ${modelStr} failed (no fallback)
Error message
Model ${modelStr} failed (no fallback) What it means
In handleComboChat, a combo model returned a non-2xx response whose status/error text failed checkFallbackError — i.e. the error is classified as non-fallbackable (e.g. 400/401/403/404, invalid request). Rather than burning the remaining combo models, the combo short-circuits: the failing upstream response is returned to the client as-is and 'Model <model> failed (no fallback)' is logged.
Source
Thrown at open-sse/services/combo.js:338
} catch {
// Ignore JSON parse errors
}
// Track earliest retryAfter across all combo models
if (retryAfter && (!earliestRetryAfter || new Date(retryAfter) < new Date(earliestRetryAfter))) {
earliestRetryAfter = retryAfter;
}
// Normalize error text to string (Worker-safe)
if (typeof errorText !== "string") {
try { errorText = JSON.stringify(errorText); } catch { errorText = String(errorText); }
}
// Check if should fallback to next model
const { shouldFallback, cooldownMs } = checkFallbackError(result.status, errorText);
if (!shouldFallback) {
log.warn("COMBO", `Model ${modelStr} failed (no fallback)`, { status: result.status });
return result;
}
// For transient errors (503/502/504), wait for cooldown before falling through
// so a briefly-overloaded provider gets a chance to recover rather than being
// skipped immediately (fixes: combo falls through on transient 503)
if (cooldownMs && cooldownMs > 0 && cooldownMs <= 5000 &&
(result.status === 503 || result.status === 502 || result.status === 504)) {
log.info("COMBO", `Model ${modelStr} transient ${result.status}, waiting ${cooldownMs}ms before next`);
await new Promise(r => setTimeout(r, cooldownMs));
}
// Fallback to next model
lastError = errorText || String(result.status);
if (!lastStatus) lastStatus = result.status;
log.warn("COMBO", `Model ${modelStr} failed, trying next`, { status: result.status });
} catch (error) {
// Catch unexpected exceptions to ensure fallback continuesView on GitHub (pinned to 90b52e06ff)
Solutions
- Inspect the returned response body/status — it is the underlying provider error; fix that cause (key, model id, parameters).
- Remove or fix the failing model in the combo definition if it cannot handle your request shape.
- Regenerate/rotate the API key or re-OAuth the affected account.
- If the error should legitimately fall through (e.g. you want 401 to trigger fallback), adjust checkFallbackError classification in open-sse/services/combo.js.
- Normalize request fields so all combo members accept them (drop unsupported params per provider).
Example fix
// before (combo def)
{ name: 'fast', models: ['openai/gpt-4o', 'ollama/llama3'] } // llama3 can't handle tools
// after
{ name: 'fast', models: ['openai/gpt-4o', 'anthropic/claude-sonnet'] } // tool-capable members Defensive patterns
Strategy: try-catch
Try / catch
const res = await chat({ model: comboName, ... });
if (!res.ok) {
const err = await res.json().catch(() => ({}));
// Non-fallbackable: fix request/key for the failing member before retrying
console.error(`combo member failed terminally: ${res.status} ${err?.error?.message}`);
} Prevention
- Keep combo members schema-compatible with your request features (tools, images, thinking).
- Rotate/verify member API keys after any credential change.
- Test each combo model individually with your exact payload shape.
- Avoid mixing providers with divergent parameter support in one combo.
When it happens
Trigger: A combo member rejects the request itself: invalid API key (401/403), malformed body or unsupported parameters for that provider (400), unknown model id (404), content-policy refusal. Any request whose error is deterministic — retrying on other models would fail the same way.
Common situations: Combo mixing providers with different request schemas (tools/images not supported by one member); stale API key on one combo model after key rotation; model name typo inside the combo definition; sending Claude-style fields to an OpenAI-only member.
Related errors
- AWS EventStream payload is not valid JSON (${error.message})
- HTTP ${result.response.status}
- MiniMax TTS upstream error
- "No JSON found in decoded code"
- "No JSON found in decoded code"
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/3a53ad3c0eca2f75.
Report an issue: GitHub.