#11349: fix(agents): do not filter fallback models by models allowlist
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
#22064: fix(failover): bypass models allowlist for configured fallback models
by winston-bepresent · 2026-02-20
91.1%
#21963: fix(cli): models fallbacks add now includes primary model in allowlist
by ashiabbott · 2026-02-20
86.8%
#16838: fix: include configured fallbacks in model allowlist
by taw0002 · 2026-02-15
86.5%
#9583: fix(models): allow models in agents.defaults.models even if not in ...
by hotzen100 · 2026-02-05
86.4%
#13626: fix(model): propagate provider model properties in fallback resolution
by mcaxtr · 2026-02-10
84.7%
#21152: fix(agents): throw FailoverError for unknown model so fallback chai...
by Mellowambience · 2026-02-19
84.2%
#9427: fix: trigger model fallback on all 4xx HTTP errors
by dbottme · 2026-02-05
84.2%
#14508: fix(models): allow forward-compat models in allowlist check
by jonisjongithub · 2026-02-12
84.0%
#13658: fix: silent model failover with fallback notification
by taw0002 · 2026-02-10
84.0%
#23816: fix(agents): model fallback skipped during session overrides and pr...
by ramezgaberiel · 2026-02-22
83.8%