{"record":{"id":"e5a338535ddeecbc","repo":"QuantumNous/new-api","slug":"authentication-rotation-has-no-active-session","errorCode":null,"errorMessage":"Authentication rotation has no active session","messagePattern":"Authentication rotation has no active session","errorType":"exception","errorClass":"AuthRotationError","httpStatus":null,"severity":"warning","filePath":"web/src/lib/auth-session.ts","lineNumber":167,"sourceCode":"  bundle: AuthBundle,\n  synchronizeTabs = true\n): void {\n  const previousSID = useAuthStore.getState().auth.session?.sid\n  authEpoch += 1\n  useAuthStore.getState().auth.setBundle(bundle)\n  if (synchronizeTabs && previousSID !== bundle.session.sid) {\n    publishAuthSessionEvent('authenticated', bundle.session.sid)\n  }\n}\n\nexport function applyAuthRotation(value: unknown): void {\n  if (!isAuthTokenRotation(value)) {\n    throw new AuthRotationError('Invalid authentication rotation response')\n  }\n\n  const auth = useAuthStore.getState().auth\n  if (!auth.user || !auth.session) {\n    throw new AuthRotationError('Authentication rotation has no active session')\n  }\n  if (value.session.sid !== auth.session.sid) {\n    throw new AuthRotationError('Authentication rotation session mismatch')\n  }\n\n  applyAuthBundle(\n    {\n      access_token: value.access_token,\n      token_type: value.token_type,\n      access_expires_at: value.access_expires_at,\n      session: value.session,\n      user: auth.user,\n    },\n    false\n  )\n}\n\nexport function clearAuthentication(","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/QuantumNous/new-api/blob/e2c7aa7b102c2075eae2377df3508658d45e88dc/web/src/lib/auth-session.ts#L149-L185","documentation":"Thrown by applyAuthRotation when a structurally valid rotation payload arrives but the Zustand auth store has no user or session object — i.e. the user is effectively logged out (or was logged out concurrently) while a token rotation response came back. Rotation refreshes credentials for an existing session; with no session there is nothing to rotate.","triggerScenarios":"A rotation response is applied after auth.user or auth.session became null: logout in this tab, a cross-tab auth sync event that cleared state, or a stale async rotation resolving after logout.","commonSituations":"User logs out in another tab (synchronizeTabs broadcast clears the store) while a refresh request was in flight; session cleanup on 401 racing with the rotation response; store reset on boot finishing after a queued rotation callback.","solutions":["Treat this error as a benign race when logout is intended: catch it where rotation is applied and drop the payload instead of surfacing an error to the user.","Cancel in-flight refreshes on logout (AbortController tied to auth state) so late rotation responses never reach applyAuthRotation.","If it fires without any logout, inspect where auth.session is cleared — an over-aggressive 401 interceptor may be resetting the store."],"exampleFix":"// before\napplyAuthRotation(rotationPayload)\n\n// after — ignore rotation after logout\ntry {\n  applyAuthRotation(rotationPayload)\n} catch (error) {\n  if (error instanceof AuthRotationError && !useAuthStore.getState().auth.session) {\n    return // user logged out mid-flight; payload is stale\n  }\n  throw error\n}","handlingStrategy":"validation","validationCode":"const auth = useAuthStore.getState().auth\nif (!auth.user || !auth.session) {\n  // user is logged out; drop the rotation payload instead of applying it\n}","typeGuard":null,"tryCatchPattern":"try {\n  applyAuthRotation(value)\n} catch (error) {\n  if (error instanceof AuthRotationError && /no active session/i.test(error.message)) {\n    return // benign logout race\n  }\n  throw error\n}","preventionTips":["Abort in-flight refreshes on logout with an AbortController tied to auth state","Ignore rotation responses older than the current auth epoch (authEpoch increments on every bundle apply)"],"tags":["auth","token-rotation","race-condition","logout"],"backgroundTag":null,"analyzedSha":"e2c7aa7b102c2075eae2377df3508658d45e88dc","analyzedAt":"2026-08-15T10:35:18.111Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}