Files
OmniRoute/tests/unit
Innokentiy Solntsev 47159ed56b fix(combo): answer 503 + Retry-After, not 404, when a weighted pool is only cooling down (#12956)
* fix(combo): answer 503 + Retry-After, not 404, when a weighted pool is only cooling down

The weighted strategy filters targets before dispatch (open circuit breaker,
provider cooldown, model lockout, availability probe) and drops them
silently. When that emptied the pool the host returned the 404
"Combo has no executable targets" with the "switch combo / reconnect the
missing providers" recovery hint — for a pool that was configured,
connected and merely cooling down. Claude Code renders a 404 from
/v1/messages as "this model may not exist".

- targetResolution.ts: the eligibility predicate now reports which gate
  excluded a target and, for the resilience gates, the remaining time;
  the exclusions of fully-excluded steps travel out of
  resolveWeightedSelection. When the weighted pool ends empty and at least
  one exclusion is a resilience timer, the pipeline returns an early 503
  and logs the reasons at warn level.
- pinRecovery.ts: buildAllTargetsCoolingDownResponse() — 503
  `all_targets_cooling_down`, Retry-After = earliest exclusion to lapse,
  every excluded target in diagnostics.excluded, `wait` recovery hint with
  retry_after_seconds; formatPreDispatchExclusions() for the log line.
- error.ts: `all_targets_cooling_down` joins the public error identifiers.
- A pool emptied only by the availability probe keeps the 404.
- docs: RESILIENCE_GUIDE debugging entry; changelog fragment.

* chore(changelog): name the fragment after PR #12956 and link issue #12954

* refactor(combo): keep weighted exhaustion below complexity ratchet

---------

Co-authored-by: insoln <is@careerum.com>
2026-09-17 16:25:49 -03:00
..