Skip to content

test(token-health): pin the real terminal-skip boundary, not the pre-exemption one - #11592

Merged
diegosouzapw merged 2 commits into
cheaper-inference:release/v3.8.51from
ntdatt812:fix/5326-expired-retry-budget-policy
Aug 26, 2026
Merged

diegosouzapw merged 2 commits into
cheaper-inference:release/v3.8.51from
ntdatt812:fix/5326-expired-retry-budget-policy

Conversation

@ntdatt812

Copy link
Copy Markdown
Contributor

Part of the "every gate is red on every branch" cleanup — one of six independent unit-test failures on release/v3.8.51.

The red test

✖ checkConnection still skips a GitHub Copilot connection expired for a
  non-no_refresh_token reason (#8182 boundary)
  actual: 'github_access_token_invalid', expected: 'invalid_grant'

The row was written, so checkConnection did not return early — the terminal skip the
assertion describes no longer applies to that fixture.

The policy moved on purpose

#8182 skipped every "expired" connection so a sweep would not waste a probe per cycle
on rows that can never self-heal. That turned out too wide: a transient OAuth failure
parks a healthy connection at "expired" and it could then never come back.
tokenHealthCheck.ts therefore grew a third exemption alongside the GitHub-Copilot and
Cursor ones:

const isRecoverableExpiredWithRetryBudget =
  conn.testStatus === "expired" &&
  conn.lastErrorType !== "account_deactivated" &&
  getExpiredRetryCount(conn) < EXPIRED_RETRY_MAX;

with the intent stated inline: "allow expired connections with retry budget remaining
to pass through so transient OAuth failures can self-heal instead of being permanently
skipped. Exhausted retries stay terminal."

The test's fixture has retry count 0 and no lastErrorType, so under the current guard
it is deliberately probed. The assertion described the pre-exemption policy.

What changed

Deleting the case would have left #8182's wasted-probe protection unguarded, so it is
replaced by the two halves of the boundary that exists now:

The probe case stubs globalThis.fetch with a 401, matching how the sibling tests in
this file isolate themselves, so it stays hermetic and does not reach the network.

Verification

# base branch
✖ checkConnection still skips a GitHub Copilot connection expired for a non-no_refresh_token reason
ℹ tests 6  ℹ pass 5  ℹ fail 1

# with this change
✔ checkConnection marks refresh-capable provider with no refresh token as expired (#5326)
✔ checkConnection leaves a connection WITH a refresh token untouched (#5326)
✔ checkConnection leaves a non-refresh provider with no refresh token untouched (#5326)
✔ checkConnection keeps GitHub Copilot access-token-only connections active
✔ checkConnection clears stale no_refresh_token state for usable GitHub Copilot connections
✔ checkConnection probes an expired GitHub connection that still has retry budget
✔ checkConnection still skips an expired GitHub connection whose account is deactivated (#8182)
ℹ tests 7  ℹ pass 7  ℹ fail 0

Test-only; no production code touched.

One thing I did not cover and would rather flag than guess at: the third terminal
path, getExpiredRetryCount(conn) >= EXPIRED_RETRY_MAX. Seeding a connection at the
retry ceiling means writing providerSpecificData.expiredRetry.count, and I could not
tell from the code whether that shape is a supported fixture or an internal detail I
would be freezing by asserting on it. Happy to add the case if you confirm which.

…exemption one

`Unit Tests fast-path` is red on every branch:

    ✖ checkConnection still skips a GitHub Copilot connection expired for a
      non-no_refresh_token reason (cheaper-inference#8182 boundary)
      actual: 'github_access_token_invalid', expected: 'invalid_grant'

cheaper-inference#8182 skipped every "expired" connection so a sweep would not waste a probe on rows
that can never self-heal. That proved too wide — a transient OAuth failure parks a
healthy connection at "expired" and it could then never come back — so
`tokenHealthCheck.ts` grew `isRecoverableExpiredWithRetryBudget`, which un-terminals an
expired connection while it still has retry budget and is not `account_deactivated`.

The assertion still described the pre-exemption policy: that ANY non-`no_refresh_token`
expired GitHub connection is skipped. Its fixture has retry count 0 and no
`lastErrorType`, so under the current guard it is deliberately probed.

Replaced with the two halves of the boundary that exists now:
  - retry budget remaining → probed, so a transient failure can self-heal;
  - `lastErrorType: "account_deactivated"` → still skipped, row untouched.

The second case keeps cheaper-inference#8182's wasted-probe protection covered where it still applies —
deleting the old case outright would have left that unguarded. The probe case stubs
`globalThis.fetch` with a 401, matching the sibling tests, so it stays hermetic.
@diegosouzapw
diegosouzapw merged commit b9fd4aa into cheaper-inference:release/v3.8.51 Aug 26, 2026
10 of 16 checks passed
diegosouzapw added a commit to HouMinXi/OmniRoute that referenced this pull request Aug 29, 2026
…obe pin after merge

Merging origin/release/v3.8.51 showed the skip assertion from cheaper-inference#11611 no
longer matches production: GitHub access-token-only expired connections
with remaining retry budget are probed via refreshCopilotToken (fetch is
called; lastHealthCheckAt is set). That boundary was pinned by cheaper-inference#11592
after the cheaper-inference#11608 carve-out. Keep the probe assertion.

Refs cheaper-inference#11611 cheaper-inference#11592

Co-authored-by: diegosouzapw <[email protected]>
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…exemption one (cheaper-inference#11592)

Merged via /merge-batch (lote 2026-08-26, v3.8.51). Boarded no worktree combinado junto com outras ~30 PRs; validação única: typecheck/complexity/cognitive-complexity/changelog-integrity verdes, file-size rebaseado onde necessário (crescimento legítimo), lint com os mesmos 228 achados pré-existentes confirmados via sonda contra o tip puro (não introduzidos por este lote), e ~370 testes focados (unit + vitest) passando. Obrigado pela contribuição.
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.

2 participants