fix(provider): retry transient 401s for a known-good key + clearer auth error (#3146)#4106
Merged
Merged
Conversation
…h error MiMo's token-plan gateway returns a transient 401 under load/quota. We surfaced every 401 as "API key missing, wrong, or expired" and never retried it, so a working key looked like it had "expired" — re-entering the same key only helped because saving it rebuilt the connection. - SendWithRetry backs off and retries a 401/403 up to maxAuthRetries when the key has authenticated before (SendOptions.RetryAuth); a key that has never worked still fails fast, so a genuinely bad key isn't hammered. - AuthError gains HasKey so the message separates "no key configured" from "server rejected your key (possibly transient)". Closes #3146
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
MiMo's
token-plangateway (token-plan-cn.xiaomimimo.com) returns a transient 401 under load / quota / gateway hiccups, not a 429. Two things turned that into an apparent dead key (#3146):RetryableStatustreats every 4xx as unrecoverable.Users reported a working key "expiring" mid-session; re-entering the same key fixed it — but only because saving the key rebuilds the connection, not because the key changed. We do not delete the key anywhere; the 401 came from the server.
Fix
SendWithRetrynow takes aSendOptionswithRetryAuth(true once a request on this client has succeeded) andKeyPresent. A 401/403 on a key that has authenticated before backs off and retries up tomaxAuthRetries(2); a key that has never worked still fails fast, so a genuinely bad key isn't hammered.AuthError.HasKeylets the UI distinguish:Wired through both the OpenAI-compatible provider (MiMo / DeepSeek / MiniMax) and Anthropic.
Tests
SendWithRetryretries a transient 401 for a known key and recovers (3 calls); gives up aftermaxAuthRetrieswithHasKey=true; still fails fast for a never-authed key.explainErrorselects the missing vs. server-rejected message byHasKey.Closes #3146