fix(combo): pre-skip targets with persisted connection cooldown and re-check on retry - #11360
Merged
diegosouzapw merged 1 commit intoAug 24, 2026
Conversation
diegosouzapw
pushed a commit
that referenced
this pull request
Aug 24, 2026
…#11355) Merged via consolidated batch validation (fix applied for a cross-PR interaction with #11360, both boarded in the same batch — see combo.ts reconciliation commit). Startup crash recovery cleared every non-terminal transient cooldown unconditionally, erasing legitimate multi-day weekly quota cooldowns on restart. Now only clears expired/unparseable ones. Own repro tests pass.
diegosouzapw
pushed a commit
that referenced
this pull request
Aug 24, 2026
…turn shape
The retry-loop recheck returned a non-conforming {ok:false, reason} object
that breaks typecheck against the established {ok, response?} contract used
everywhere else in this function. Aligns with the pre-dispatch skip pattern
(return null after fallbackCount++), matching the PR's own intent: skip this
target and move to the next, not error the whole attempt.
This is a live fix — the broken shape reached origin/release/v3.8.50 via
#11360's own squash-merge and was breaking typecheck:core until now.
diegosouzapw
added a commit
that referenced
this pull request
Sep 1, 2026
…cannot dark a pool (#12168) (#12285) getPersistedConnectionCooldownSkipReason() returned a skip for ANY connection whose testStatus was `unavailable`, with no elapsed-cooldown check: if (status === "unavailable") return `Skipping ...`; That is the raw-label anti-pattern AGENTS.md warns about ("check whether code is reading raw state instead of using getStatus()/canExecute()") — the resilience layers are meant to recover lazily. The sibling helper directly above it, getConnectionStatusQuotaCutoffReason(), does require hasFutureRateLimitUntil() before treating `unavailable` as blocking. Its stated justification — "Lazy recovery is unaffected: clearAccountError() resets the status on first success" — does not hold on this path. This gate runs BEFORE dispatch, so it prevents the very successful request that would call clearAccountError(). And a row whose rateLimitedUntil is absent cannot be rescued by the out-of-band recovery job either, because hasElapsedCooldown() there requires a timestamp to be present. Net effect reported in #12168: an entire combo pool answering ALL_TARGETS_SKIPPED with recordedAttempts === 0 — zero upstream attempts, no path back to healthy. The original intent (do not burst into a connection AUTH just retired, before the timestamp lands) is preserved, but bounded: the bare label is honoured only while lastErrorAt is inside a grace window, mirroring ERROR_LABEL_GRACE_MS in src/lib/quota/connectionRecovery.ts so the two never disagree about whether a label is still meaningful. Past the window the request goes through, and one real attempt either succeeds (clearing the status) or re-arms the cooldown with a fresh timestamp. Regression introduced by #11360, shipped in v3.8.50. Two assertions in repro-combo-persisted-cooldown-preskip.test.ts encoded the buggy behavior as intended ("skips an unavailable connection whose cooldown already expired") and are realigned to the corrected contract, plus a case for the orphan state (unavailable with no timestamps at all).
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…diegosouzapw#11355) Merged via consolidated batch validation (fix applied for a cross-PR interaction with diegosouzapw#11360, both boarded in the same batch — see combo.ts reconciliation commit). Startup crash recovery cleared every non-terminal transient cooldown unconditionally, erasing legitimate multi-day weekly quota cooldowns on restart. Now only clears expired/unparseable ones. Own repro tests pass.
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…e-check on retry (diegosouzapw#11360) Merged via consolidated batch validation, with one fix applied during batch validation: the retry-loop persisted-cooldown recheck returned a non-conforming {ok:false, reason} shape that failed typecheck against the established {ok, response?} contract — aligned it with the pre-dispatch skip pattern (return null after fallbackCount++), matching this PR's own intent (skip the target, don't error the whole attempt). Pre-skips combo targets with a persisted connection cooldown and re-checks fresh before transient retries. Own regression suite (13/13, including the fixed retry-recheck path) passes.
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…n recheck return shape
The retry-loop recheck returned a non-conforming {ok:false, reason} object
that breaks typecheck against the established {ok, response?} contract used
everywhere else in this function. Aligns with the pre-dispatch skip pattern
(return null after fallbackCount++), matching the PR's own intent: skip this
target and move to the next, not error the whole attempt.
This is a live fix — the broken shape reached origin/release/v3.8.50 via
diegosouzapw#11360's own squash-merge and was breaking typecheck:core until now.
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…cannot dark a pool (diegosouzapw#12168) (diegosouzapw#12285) getPersistedConnectionCooldownSkipReason() returned a skip for ANY connection whose testStatus was `unavailable`, with no elapsed-cooldown check: if (status === "unavailable") return `Skipping ...`; That is the raw-label anti-pattern AGENTS.md warns about ("check whether code is reading raw state instead of using getStatus()/canExecute()") — the resilience layers are meant to recover lazily. The sibling helper directly above it, getConnectionStatusQuotaCutoffReason(), does require hasFutureRateLimitUntil() before treating `unavailable` as blocking. Its stated justification — "Lazy recovery is unaffected: clearAccountError() resets the status on first success" — does not hold on this path. This gate runs BEFORE dispatch, so it prevents the very successful request that would call clearAccountError(). And a row whose rateLimitedUntil is absent cannot be rescued by the out-of-band recovery job either, because hasElapsedCooldown() there requires a timestamp to be present. Net effect reported in diegosouzapw#12168: an entire combo pool answering ALL_TARGETS_SKIPPED with recordedAttempts === 0 — zero upstream attempts, no path back to healthy. The original intent (do not burst into a connection AUTH just retired, before the timestamp lands) is preserved, but bounded: the bare label is honoured only while lastErrorAt is inside a grace window, mirroring ERROR_LABEL_GRACE_MS in src/lib/quota/connectionRecovery.ts so the two never disagree about whether a label is still meaningful. Past the window the request goes through, and one real attempt either succeeds (clearing the status) or re-arms the cooldown with a fresh timestamp. Regression introduced by diegosouzapw#11360, shipped in v3.8.50. Two assertions in repro-combo-persisted-cooldown-preskip.test.ts encoded the buggy behavior as intended ("skips an unavailable connection whose cooldown already expired") and are realigned to the corrected contract, plus a case for the orphan state (unavailable with no timestamps at all).
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.
Summary
Fixes #11359.
Pre-skips combo targets whose connections already carry a persisted cooldown or blocking status in SQLite, and performs a fresh DB read before transient retries so that newly persisted cooldowns from sibling requests are respected immediately.
Root Cause
handleComboChatchecked circuit breakers, global provider cooldowns, and semaphores before dispatch, but did not check the persisted connectionrate_limited_untilorunavailablestatus. The cooldown was only detected during credential lookup after an attempt had already begun. Furthermore, during transient retries, the 5-second connection cache could serve stale "active" data even after a 429 had updated the DB.Implementation
getPersistedConnectionCooldownSkipReasonandresolvePersistedConnectionCooldownSkipReasontoopen-sse/services/combo/comboPredicates.ts.open-sse/services/combo.ts.retry > 0) to immediately recognize cooldowns written mid-flight by sibling requests.allowRateLimitedConnectionbypass.Tests & Verification
node --import tsx/esm --test tests/unit/repro-combo-persisted-cooldown-preskip.test.ts(13/13 pass)git diff --check(pass)