Skip to content

Fail fast on auth errors instead of polling - #578

Merged
luismeyer merged 5 commits into
mainfrom
fix-polling-keeps-process-alive
Oct 28, 2026
Merged

luismeyer merged 5 commits into
mainfrom
fix-polling-keeps-process-alive

Conversation

@luismeyer

@luismeyer luismeyer commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Since 1.10.0, a client whose stream gives up falls back to polling. Polling stopped on a 401 but retried a missing OIDC token forever. With no credentials (scripts and test files outside Vercel), the ref'd interval kept the process alive, so node --test hung until CI killed it (vercel/api's cse-agent tests).

The stream and polling use the same credential, so an auth failure on one means the other fails the same way. Auth failures (a 401, or a missing OIDC token) now end the source chain right away:

  • Stream fails on auth (at startup, or when it gives up later): no polling. The client goes straight to degraded, where reads revalidate over HTTP on demand. exhausted now carries the 401/token error as its reason.
  • Polling as the primary source (stream: false): the first poll's auth failure stops the interval and degrades the client.
  • fetchDatafile no longer retries a missing OIDC token.
  • The unauthorized flag covers missing tokens too, so initialization skips the final blocking fetch and usage tracking doesn't send events that can't authenticate.

Implementation: OIDC failures throw a typed OidcTokenError (same message, original error as cause), and isAuthError() checks for either case. Retry exhaustion without an auth error still falls back to polling, as before.

Tests: tests that pinned the old poll-after-auth-failure behavior now assert the fast fail. New tests cover a missing token on the stream, a missing token with polling as primary, and no token retry in fetchDatafile. The 401 fast-fail now makes 2 requests instead of 3.

Verified against vercel/api: agents/cse/agent/lib/model-config.test.ts hangs on 1.10.2 and finishes in ~0.2s with this build.

🤖 Generated with Claude Code

Since 1.10.0 an OIDC client whose stream can't connect falls back to
polling. A missing token is not a 401, so polling never stops, and its
ref'd interval keeps short-lived processes (scripts, test files) from
exiting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
flags-playground Ready Ready Preview, v0 Oct 28, 2026 11:02am UTC
flags-sdk-dev Ready Ready Preview, v0 Oct 28, 2026 11:02am UTC
flags-sdk-flagsmith Ready Ready Preview, v0 Oct 28, 2026 11:02am UTC
flags-sdk-growthbook Ready Ready Preview, v0 Oct 28, 2026 11:02am UTC
flags-sdk-launchdarkly Ready Ready Preview, v0 Oct 28, 2026 11:02am UTC
flags-sdk-openfeature Ready Ready Preview, v0 Oct 28, 2026 11:02am UTC
flags-sdk-posthog Ready Ready Preview, v0 Oct 28, 2026 11:02am UTC
flags-sdk-reflag Ready Ready Preview, v0 Oct 28, 2026 11:02am UTC
flags-sdk-snippets Ready Ready Preview, v0 Oct 28, 2026 11:02am UTC
flags-sdk-statsig Ready Ready Preview, v0 Oct 28, 2026 11:02am UTC
flags-sdk-sveltekit-snippets Ready Ready Preview, v0 Oct 28, 2026 11:02am UTC
shirt-shop Ready Ready Preview, v0 Oct 28, 2026 11:02am UTC
shirt-shop-api Ready Ready Preview, v0 Oct 28, 2026 11:02am UTC

Polling gave up on a 401 but kept retrying a missing OIDC token forever,
so a client without credentials kept scripts and test files running.
Treat a token failure like a 401 instead of unref'ing the interval.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
try {
return await getVercelOidcToken();
} catch (error) {
throw new OidcTokenError(error);

@vincent-derks vincent-derks Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we also verify that it is an actual token auth issue, and not some random 500 or a network issue? Because in those cases we'd still want to retry, or not?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, you're right. getVercelOidcToken refreshes a missing or expired token over the network (OAuth discovery, the token refresh, and POST /v1/projects/:id/token), so a 500 or a network error there would also have ended up as OidcTokenError and stopped retries.

Fixed in 4c989b3. @vercel/oidc flattens every failure into one message with no cause, so OidcTokenError is now raised only for the messages that mean there are no credentials at all: project not linked (vc link), CLI not logged in (vercel login), or the token header missing on the edge. Anything else, like a failed refresh, is thrown as a plain error and retried as before. Tests for both sides are in controller/auth.test.ts.

A failed token refresh can be transient, so keep retrying it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot mentioned this pull request Oct 28, 2026

This branch was successfully deployed

14 active deployments
Preview – flags-sdk-dev — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
Preview – flags-sdk-reflag — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
Preview – flags-sdk-snippets — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
Preview – flags-sdk-sveltekit-snippets — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
Preview – flags-playground — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
Preview – flags-sdk-vercel — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
Preview – flags-sdk-flagsmith — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
Preview – flags-sdk-posthog — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
Preview – flags-sdk-growthbook — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
Preview – flags-sdk-launchdarkly — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
Preview – flags-sdk-statsig — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
Preview – flags-sdk-openfeature — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
Preview – shirt-shop-api — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
Preview – shirt-shop — 4c989b32 Deployed Oct 28, 2026 by vercel[bot]
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