Skip to content

fix(combo): report one model's status with that same model's message - #3873

Open
ntdatt812 wants to merge 1 commit into
decolua:masterfrom
ntdatt812:fix/3729-combo-error-coherence
Open

ntdatt812 wants to merge 1 commit into
decolua:masterfrom
ntdatt812:fix/3729-combo-error-coherence

Conversation

@ntdatt812

Copy link
Copy Markdown
Contributor

Addresses #3729.

The report's diagnosis does not hold

#3729 suggests the Console error is "not recognized by the fallback heuristic in open-sse/services/accountFallback.js" and asks for the phrase to be added. But checkFallbackError returns shouldFallback: true on every path, including its default:

// Default: transient cooldown for any unmatched error
return { shouldFallback: true, cooldownMs: TRANSIENT_COOLDOWN_MS };

Driving handleComboChat with the exact reported failure confirms it — the combo advances:

TRIED: [ 'cl/z-ai/glm-5.3-flash', 'oc/big-pickle' ]   STATUS: 200

Adding "Model is unavailable" to a match list would have changed nothing.

What is actually wrong

When the list is exhausted, the reply mixes two different attempts:

lastError = errorText || String(result.status);   // the LAST failure
if (!lastStatus) lastStatus = result.status;      // the FIRST failure

Same probe, three models, all failing:

FINAL STATUS: 403      FINAL MSG: "second model says 429"

A 403 from the model tried first, carrying the text of a 429 from a later one. That reads as a single provider returning a nonsensical pair — which is exactly the HTTP 403: [400]: {...} shape in the report, and why it looked like fallback had never run.

The change

Status and message are recorded together, so the client sees the failure that actually ended the combo. The thrown-exception branch is paired the same way — it reports 500 and now carries the message that went with it.

Verification

tests/unit/combo-failure-pairing.test.js — 4 passed. Restoring if (!lastStatus) fails exactly the pairing test.

One of those four pins that a Console 403 still falls through to a working model. That behaviour already works; the test is there so a later change to the fallback rules cannot quietly remove it.

Pre-existing, untouched: combo-autoswitch.test.js fails 4 of 22 on master (detectRequiredCapabilities > web_search tool -> search, reorderByCapabilities > keeps order when no model matches) — same test names with this change stashed, checked rather than assumed.

This does not close #3729 by itself if the reporter's three models were all genuinely unavailable; it makes the failure legible so that case can be told apart from a broken fallback.

…ecolua#3729)

When every model in a combo failed, the reply mixed two of them:

    lastError = errorText || String(result.status);   // last failure
    if (!lastStatus) lastStatus = result.status;      // first failure

so a combo that ran out of models answered with, say, a 403 from the
Console model tried first, carrying the text of the 429 the next model
returned. That pair reads as one provider behaving incoherently, and is
the shape reported in decolua#3729 as "403-wrapped-400".

The report's diagnosis does not hold. checkFallbackError returns
shouldFallback: true on every path, including its default, so no phrase
list gates the advance; driving handleComboChat with a Console 403
followed by a working model does advance and return 200. Adding "Model is
unavailable" to a match list would have changed nothing. What made
fallback look broken was the error it produced after exhausting the list,
which named a status and a message from different attempts.

Status and message are now recorded together, so the client sees the
failure that actually ended the combo. The thrown-exception path is
paired the same way: it reports 500, and now carries the message that
went with it.

Verified with tests/unit/combo-failure-pairing.test.js (4 passed), which
also pins that a Console 403 still falls through -- behaviour that already
worked and should not be lost to a later change in the fallback rules.
Restoring `if (!lastStatus)` fails exactly the pairing test.

Pre-existing and untouched: combo-autoswitch.test.js fails 4 of 22
(detectRequiredCapabilities, reorderByCapabilities) on master with the
same names.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Combo fallback doesn't trigger on Console provider's 403-wrapped-400 "Model is unavailable" error

1 participant