Skip to content

fix(providers): carve cookie-auth providers out of terminal 401 'expired' classification so one 401 cooldowns instead of killing the connection - #8321

Merged
diegosouzapw merged 1 commit into
release/v3.8.49from
fix/8200-perplexity-web-401-cooldown
Jul 24, 2026
Merged

diegosouzapw merged 1 commit into
release/v3.8.49from
fix/8200-perplexity-web-401-cooldown

Conversation

@diegosouzapw

@diegosouzapw diegosouzapw commented Jul 23, 2026 •

Copy link
Copy Markdown
Collaborator

Refs #8200 (part A — one-401 terminal misclassification fixed; part B cookie rotation/keepalive tracked as follow-up, issue kept open)

Root cause

src/sse/services/auth.ts::resolveTerminalConnectionStatus() mapped ANY HTTP 401
that wasn't classified OAUTH_INVALID_TOKEN/PROJECT_ROUTE_ERROR to the TERMINAL
testStatus: "expired" via the fallthrough providerErrorType === UNAUTHORIZED || status === 401. perplexity-web is registered authType: "apikey" (cookie-based),
so its recoverable session-expiry 401s went through classifyProviderError() as plain
UNAUTHORIZED and landed on the terminal branch — with checkFallbackError's
status_401 rule giving a hard-coded cooldownMs: 0, markAccountUnavailable()
persisted a permanent testStatus: "expired" on the very first 401. Then
getProviderCredentials() filters connections via isTerminalConnectionStatus()
regardless of isActive, so the connection dropped out of selection on the next
request, surfacing as 404 No active credentials for provider: perplexity-web —
even though the row stayed is_active=1 and the account was still configured.

This 401→expired mapping is intentional/tested for ordinary API-key providers, but
perplexity-web (and other cookie/session-auth providers) had no carve-out — unlike
grok-web, which already gets a non-terminal, mode-local lockout for its 403s.

Fix

Added a provider parameter to resolveTerminalConnectionStatus() and a small
isRecoverableCookieAuth401() helper: a 401/UNAUTHORIZED classification on any
provider registered in WEB_COOKIE_PROVIDERS (perplexity-web, grok-web, etc.) is now
routed to the ordinary recoverable-cooldown path instead of the zero-cooldown terminal
expired path — mirroring the existing OAuth-invalid-token / grok-web carve-outs.
ACCOUNT_DEACTIVATED (a confirmed permanent signal) is explicitly excluded from the
carve-out, so genuine terminal bans still terminal-expire.

Scoped strictly to this issue: no changes to cookie rotation/Set-Cookie capture
(issue's part B) — that is tracked separately and is a larger, independently-testable
change (new mergeRefreshedCookie-style helper + executor wiring) that this repro
does not cover.

TDD evidence (Hard Rule #18)

New permanent regression test: tests/unit/8200-perplexity-web-401-cooldown.test.ts

RED (before fix):

AssertionError [ERR_ASSERTION]: a recoverable perplexity-web 401 must not be classified terminal 'expired'
  actual: 'expired', expected: 'expired', operator: 'notStrictEqual'

GREEN (after fix):

✔ BUG #8200: single perplexity-web 401 (cookie expiry) does not terminal-expire the only connection
✔ markAccountUnavailable keeps the existing 401->expired terminal mapping for plain apikey providers
ℹ tests 2, pass 2, fail 0

Sibling tests re-run and green: tests/unit/auth-terminal-status.test.ts (10/10),
tests/unit/auth-ollama-cloud-per-model-403-3027.test.ts (3/3),
tests/unit/combo-skip-conn-disable-plugin-block-7806.test.ts (4/4),
tests/unit/perplexity-web.test.ts (31/31).

Gates run

  • node scripts/check/check-file-size.mjs → OK (src/sse/services/auth.ts 2461 lines, under the 2462 baseline)
  • node scripts/check/check-complexity.mjs → pre-existing repo-wide drift (2167 vs baseline 2130) confirmed identical on a clean origin/release/v3.8.49 probe worktree — not introduced by this diff; touched functions have zero reported violations
  • node scripts/check/check-cognitive-complexity.mjs → same pre-existing drift confirmed (956 vs baseline 951 on both this branch and the pure tip)
  • npm run typecheck:core → exit 0
  • npx eslint --suppressions-location config/quality/eslint-suppressions.json src/sse/services/auth.ts tests/unit/8200-perplexity-web-401-cooldown.test.ts → exit 0
  • node scripts/check/check-changelog-integrity.mjs → OK

Related

PR #8201 (same reporter) proposed essentially this diagnosis + a cookie-rotation
follow-up but was closed for catastrophic base drift (547 files, diff exceeded
GitHub's API limit), not on technical merits. This PR is a fresh, focused
implementation off the current release/v3.8.49 tip covering part (A) of that
diagnosis, proven by a clean TDD repro.

…red' classification so one 401 cooldowns instead of killing the connection
@diegosouzapw
diegosouzapw merged commit 35541c0 into release/v3.8.49 Jul 24, 2026
10 checks passed
@diegosouzapw
diegosouzapw deleted the fix/8200-perplexity-web-401-cooldown branch July 24, 2026 15:36
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
…red' classification so one 401 cooldowns instead of killing the connection (cheaper-inference#8321)
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…red' classification so one 401 cooldowns instead of killing the connection (cheaper-inference#8321)
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.

1 participant