← Back to PRs

#11349: fix(agents): do not filter fallback models by models allowlist

by liuxiaopai-ai open 2026-02-07 18:29 View on GitHub →
agents stale
## Summary When `agents.defaults.models` (the models allowlist) is configured, fallback models from `model.fallbacks` were silently filtered out, causing `"All models failed (1)"` even when valid fallback providers were configured and available. ## Root Cause In `resolveFallbackCandidates()`, fallback models were added with `enforceAllowlist=true`: ```typescript addCandidate(resolved.ref, true); // ← enforces allowlist ``` The `models` allowlist is meant to gate ad-hoc model resolution (aliases, catalog filtering), but fallback entries are **explicitly configured by the user** in `model.fallbacks`. Filtering them defeats the purpose of having fallbacks. **Example config that triggers the bug:** ```json { "agents": { "defaults": { "model": { "primary": "anthropic/claude-sonnet-4", "fallbacks": ["openai/gpt-4o", "ollama/llama-3"] }, "models": { "anthropic/claude-sonnet-4": {}, "anthropic/claude-opus-4": {} } } } } ``` Result: `candidates` array only contains the primary model. When Anthropic is in cooldown, no fallbacks are attempted. ## Fix Change `enforceAllowlist` to `false` for fallback entries in both: - `resolveFallbackCandidates()` (text model fallbacks) - `resolveImageFallbackCandidates()` (image model fallbacks) ## Tests Added 2 new tests: - Fallback models included despite not being in allowlist - All fallbacks attempted sequentially when primary fails and allowlist would have filtered them All 21 tests pass (19 existing + 2 new). Closes #5763 <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR changes model fallback resolution so that entries explicitly configured in `agents.defaults.model.fallbacks` (and `agents.defaults.imageModel.fallbacks`) are no longer filtered out by the `agents.defaults.models` allowlist. Concretely, `resolveFallbackCandidates()` and `resolveImageFallbackCandidates()` now add fallback candidates with `enforceAllowlist=false`, ensuring the system will still attempt configured fallback providers/models when the primary provider is unavailable (e.g., in cooldown), instead of producing an "All models failed (1)" situation with no fallback attempts. Two new tests cover the allowlist + fallback interaction for text models. <h3>Confidence Score: 4/5</h3> - This PR looks safe to merge and fixes a clear fallback-resolution bug. - The change is narrowly scoped (only toggles allowlist enforcement for explicitly configured fallback entries) and matches the intended semantics described in the PR. No other logic paths were modified. I couldn’t execute the test suite in this environment due to missing package managers (pnpm/npm), so the score is slightly below 5 despite the tests looking correct by inspection. - No files require special attention <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs