#22064: fix(failover): bypass models allowlist for configured fallback models
agents
size: S
## Problem
Closes #19249
When `agents.defaults.models` (model catalog/aliases) is configured with any entries, it creates an allowlist that filters which models can be used. Fallback models from `agents.defaults.model.fallbacks` were being checked against this allowlist with `enforceAllowlist: true`, which silently dropped any fallback model not also listed in the catalog.
This meant that when the primary model hit a rate limit (429) and threw a `FailoverError`, the fallback candidates list was empty (filtered out by the allowlist). With only 1 candidate (the primary), `throwFallbackFailureSummary` re-threw the original FailoverError directly, and no fallback was attempted.
### Reproduction
1. Configure `agents.defaults.model.fallbacks` with models from a different provider (e.g., OpenRouter)
2. Configure `agents.defaults.models` with any entries (e.g., aliases for the primary model)
3. Trigger a rate limit on the primary model
4. Observe: agents stay stuck on the rate-limited model; fallbacks are never attempted
## Fix
Changed fallback models to bypass the allowlist check (`enforceAllowlist: false`). These models are explicitly configured by the user as failover targets in `agents.defaults.model.fallbacks` and must always be reachable during runtime failover, regardless of the model catalog configuration.
Same fix applied to image model fallbacks (`agents.defaults.imageModel.fallbacks`) for consistency.
## Tests
Added `src/agents/model-fallback.allowlist.test.ts` with 3 regression tests:
- Fallback models bypass the models allowlist (the core bug)
- Fallback models are reached on FailoverError from embedded runner
- Baseline: fallbacks work without allowlist (sanity check)
All 3 tests **fail** without the fix and **pass** with it. Existing probe tests remain green.
## Changes
- `src/agents/model-fallback.ts`: Change `addCandidate(resolved.ref, true)` → `addCandidate(resolved.ref, false)` for both text and image fallbacks
- `src/agents/model-fallback.allowlist.test.ts`: New test file
- `src/agents/model-fallback.e2e.test.ts`: Additional test case
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Changed fallback models to bypass the `agents.defaults.models` allowlist by passing `enforceAllowlist: false` instead of `true` to `addCandidate()` calls in `src/agents/model-fallback.ts:247` and `addRaw()` in `src/agents/model-fallback.ts:177`. This allows explicitly configured fallback models to be reached during runtime failover even when they're not listed in the model catalog.
- Fixed the core bug where fallback models were silently filtered out by the allowlist, leaving no candidates when the primary model hit rate limits
- Applied the same fix to both text model fallbacks (`agents.defaults.model.fallbacks`) and image model fallbacks (`agents.defaults.imageModel.fallbacks`) for consistency
- Added comprehensive regression tests in `model-fallback.allowlist.test.ts` covering the bug scenario, embedded runner errors, and baseline functionality
- All tests pass with the fix and fail without it, confirming the fix resolves the issue
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The fix is surgical and well-tested: it changes only two boolean parameters from `true` to `false`, bypassing the allowlist check for explicitly configured fallback models. The change is backed by comprehensive regression tests that fail without the fix and pass with it. The logic is sound - fallback models are intentionally configured by users and should always be reachable during failover, regardless of the model catalog. No existing functionality is broken, and the fix aligns with the clear intent of the fallback configuration
- No files require special attention
<sub>Last reviewed commit: 3670fd9</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#11349: fix(agents): do not filter fallback models by models allowlist
by liuxiaopai-ai · 2026-02-07
91.1%
#21963: fix(cli): models fallbacks add now includes primary model in allowlist
by ashiabbott · 2026-02-20
87.4%
#21152: fix(agents): throw FailoverError for unknown model so fallback chai...
by Mellowambience · 2026-02-19
87.3%
#23816: fix(agents): model fallback skipped during session overrides and pr...
by ramezgaberiel · 2026-02-22
86.5%
#16838: fix: include configured fallbacks in model allowlist
by taw0002 · 2026-02-15
85.1%
#9427: fix: trigger model fallback on all 4xx HTTP errors
by dbottme · 2026-02-05
85.0%
#20275: fix(cli): include primary model in allowlist when adding fallbacks
by MFS-code · 2026-02-18
84.9%
#23033: fix: continue to fallbacks when first fallback throws unclassified ...
by ismsaa · 2026-02-21
84.6%
#19252: fix(agents): continue model fallback on failover text payloads
by mahsumaktas · 2026-02-17
84.0%
#13658: fix: silent model failover with fallback notification
by taw0002 · 2026-02-10
83.6%