Target branch
main
Classification
Bug (auth, admin frontend; dev-mode symptom, latent race in production)
Problem
On next dev, loading a page with no access token in memory fires two concurrent [Auth] No access token found. Attempting to refresh... calls (React StrictMode double effect). The first refresh succeeds and rotates the refresh token; the second sends the now-stale token, receives 401, and auth-store treats it as a hard failure and logs the user out — every hard navigation bounces to /login.
Observed at packages/frontend/src/stores/auth-store.ts:291-295 while testing #914:
No access token found. Attempting to refresh... ×2 (~2ms apart)
Token refreshed successfully
POST /api/v1/auth/refresh → 401
Token refresh failed. User needs to log in again. → redirect to login
Expected behavior
Concurrent refresh attempts should be deduplicated (single in-flight refresh promise shared by callers). A refresh 401 that races a successful rotation should not destroy a session that just obtained a valid access token.
Suspected failure path
auth-store.ts refresh flow has no mutex/in-flight promise; refresh-token rotation on the backend invalidates the first token as soon as the second request is in flight.
Repro
pnpm dev the admin frontend against the quickstart backend
- Log in, then hard-reload any authenticated page
- Watch console: double refresh warning, then 401 + forced logout
Scope
packages/frontend/src/stores/auth-store.ts (frontend-user likely shares the pattern — verify)
Acceptance criteria
Out of scope
- Backend refresh-token rotation semantics
Found while testing #914 / #915.
Target branch
mainClassification
Bug (auth, admin frontend; dev-mode symptom, latent race in production)
Problem
On
next dev, loading a page with no access token in memory fires two concurrent[Auth] No access token found. Attempting to refresh...calls (React StrictMode double effect). The first refresh succeeds and rotates the refresh token; the second sends the now-stale token, receives 401, andauth-storetreats it as a hard failure and logs the user out — every hard navigation bounces to/login.Observed at
packages/frontend/src/stores/auth-store.ts:291-295while testing #914:No access token found. Attempting to refresh...×2 (~2ms apart)Token refreshed successfullyPOST /api/v1/auth/refresh→ 401Token refresh failed. User needs to log in again.→ redirect to loginExpected behavior
Concurrent refresh attempts should be deduplicated (single in-flight refresh promise shared by callers). A refresh 401 that races a successful rotation should not destroy a session that just obtained a valid access token.
Suspected failure path
auth-store.tsrefresh flow has no mutex/in-flight promise; refresh-token rotation on the backend invalidates the first token as soon as the second request is in flight.Repro
pnpm devthe admin frontend against the quickstart backendScope
packages/frontend/src/stores/auth-store.ts(frontend-user likely shares the pattern — verify)Acceptance criteria
next devno longer bounce to/loginOut of scope
Found while testing #914 / #915.