Skip to content

Duplicate /api/auth/convex/token requests during Convex auth handshake #377

Description

@jperezrealini

Description

When using @convex-dev/better-auth/react with ConvexBetterAuthProvider, I see two requests to /api/auth/convex/token during login / Convex auth initialization.

This appears to happen because Convex calls the provided fetchAccessToken twice as part of its auth handshake:

  1. ConvexProviderWithAuth mounts or the Better Auth session changes and calls client.setAuth(fetchAccessToken, ...).
  2. Convex auth manager calls fetchAccessToken({ forceRefreshToken: false }), which maps to authClient.convex.token().
  3. After the Convex websocket confirms the token via an auth transition, Convex calls refetchToken().
  4. That calls fetchAccessToken({ forceRefreshToken: true }), which again maps to authClient.convex.token().

So a single login/auth initialization results in two network calls to the same endpoint.

Stack traces / observed paths

First request:

betterFetch
$fetch
better-auth client proxy
@convex-dev/better-auth/react fetchAccessToken
fetchTokenAndGuardAgainstRace
setConfig
setAuth
ConvexProviderWithAuth

Second request:

betterFetch
$fetch
better-auth client proxy
@convex-dev/better-auth/react fetchAccessToken
fetchTokenAndGuardAgainstRace
refetchToken
onTransition
onMessage
ws.onmessage

Expected behavior

Ideally a single login/auth initialization would only call /api/auth/convex/token once, or the second call would be avoided/deduped if the token just fetched is already fresh enough.

Actual behavior

Two requests are made to /api/auth/convex/token for one auth initialization.

Notes

The Better Auth React provider currently caches non-forced token fetches, but the second Convex call is forced with forceRefreshToken: true, so it bypasses the non-forced pending/cached token path.

This may be expected from Convex's auth state machine, but from the app/network layer it looks redundant because both calls hit the same Better Auth endpoint immediately after login.

Environment

  • @convex-dev/better-auth: 0.12.2
  • better-auth: 1.6.10
  • convex: 1.38.0
  • React app using TanStack Start
  • Browser devtools on localhost

Related context

A similar duplicate-session-fetch issue exists in Better Auth itself for /get-session, where separate refresh paths can cause redundant network calls: better-auth/better-auth#9613

This issue is specifically about duplicate /api/auth/convex/token calls through @convex-dev/better-auth/react + Convex auth refresh behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions