Skip to content

fix(keychain): keep using a valid connector token when its refresh fails - #644

Open
koreankop wants to merge 1 commit into
yc-software:mainfrom
koreankop:connector-token-refresh-resilience
Open

fix(keychain): keep using a valid connector token when its refresh fails#644
koreankop wants to merge 1 commit into
yc-software:mainfrom
koreankop:connector-token-refresh-resilience

Conversation

@koreankop

@koreankop koreankop commented Aug 21, 2026

Copy link
Copy Markdown

Summary

A connector token refresh fires as soon as the token enters the refresh margin, and its result is returned unconditionally. One failed refresh therefore hands the turn nothing — even though the stored token usually has minutes of life left and would have worked fine.

That turns a brief network problem into a credential outage. Observed on a machine waking from sleep with DNS not yet up: a run of [keychain] connector token refresh failed for <host>: fetch failed, tools that then had no token at all, and scheduled work coming back as provider 401s and "needs reconnect" — for grants that were never revoked. Because the orchestrator walks every connector host, a single bad minute takes out the whole set.

This change falls back to the stored token when a refresh fails and the token has not yet reached its expiry skew. The failure is still stamped on the record, so a genuine revocation still surfaces as needs-reconnect the moment the token really expires; the outage window just stops taking working credentials down with it.

No retries, no new knobs, no added latency: the fallback path is the one that was already returning null.

Test plan

node --experimental-test-module-mocks --test test/keychain.test.ts — 45/45 pass, tsc --noEmit and eslint clean. Three new cases:

  • refresh throws while the stored token still has 5 minutes: the stored token is returned, refreshFailedAt is recorded, and status does not report needsReconnect (this one fails on main);
  • refresh throws and the stored token is inside the expiry skew: nothing is returned and status reports needsReconnect;
  • refresh succeeds: the fresh token still wins over the stored one.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

A refresh runs as soon as a token enters the refresh margin, and its result was
returned unconditionally — so one failed refresh handed the turn nothing, even
though the stored token typically had minutes of life left. A machine waking
with DNS not yet up therefore knocked healthy connectors out for the whole
turn: refreshes failed with 'fetch failed', tools got no token, and work whose
grant was perfectly fine came back as 401s and 'needs reconnect'.

Fall back to the stored token when a refresh fails and the token has not yet
reached its expiry skew. The failure is still recorded on the record, so a
genuine revocation still surfaces as needs-reconnect the moment the token
actually expires — the outage window just stops taking working credentials
down with it.
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