2237273869
## Summary - When returning to the app after idle (or after a deploy), the expired access token causes multiple simultaneous GraphQL queries to fail with `UNAUTHENTICATED`. Previously, each failure independently triggered its own `renewToken` call with the same refresh token. If **any single** renewal failed (e.g. server briefly slow after a deploy), the `catch` handler would nuke the session and redirect to sign-in — even if another concurrent renewal had already succeeded and written valid tokens. - This adds a shared `renewalPromise` so that only the first `UNAUTHENTICATED` error triggers a server-side renewal. All concurrent callers await the same promise and replay their operations once it resolves. This eliminates redundant refresh token rotation on the server and removes the race condition where a straggling failure could log out an already-renewed session. ## Test plan - [ ] Log in, wait >30 minutes (or manually expire the access token), then interact with the app — should silently renew without redirect to sign-in - [ ] Open browser DevTools Network tab, trigger the above scenario, and verify only **one** `renewToken` mutation is sent (instead of N) - [ ] With server temporarily stopped, verify that a genuine renewal failure still correctly redirects to sign-in (single `onUnauthenticatedError` call) - [ ] Open multiple browser tabs, let access tokens expire, interact in one tab — other tabs should also recover gracefully on their next request Made with [Cursor](https://cursor.com) --------- Co-authored-by: Cursor <cursoragent@cursor.com>
Run yarn dev while server running on port 3000