QuantumNous/new-api · error · AuthRotationError

Authentication rotation session mismatch

Error message

Authentication rotation session mismatch

What it means

Thrown by applyAuthRotation when the rotation payload's session.sid differs from the sid currently in the auth store. Sessions are identified by sid; a mismatch means the response belongs to a different session (new login elsewhere, session re-created by the server, or cross-tab drift), and applying it would silently merge two identities.

Source

Thrown at web/src/lib/auth-session.ts:170

  const previousSID = useAuthStore.getState().auth.session?.sid
  authEpoch += 1
  useAuthStore.getState().auth.setBundle(bundle)
  if (synchronizeTabs && previousSID !== bundle.session.sid) {
    publishAuthSessionEvent('authenticated', bundle.session.sid)
  }
}

export function applyAuthRotation(value: unknown): void {
  if (!isAuthTokenRotation(value)) {
    throw new AuthRotationError('Invalid authentication rotation response')
  }

  const auth = useAuthStore.getState().auth
  if (!auth.user || !auth.session) {
    throw new AuthRotationError('Authentication rotation has no active session')
  }
  if (value.session.sid !== auth.session.sid) {
    throw new AuthRotationError('Authentication rotation session mismatch')
  }

  applyAuthBundle(
    {
      access_token: value.access_token,
      token_type: value.token_type,
      access_expires_at: value.access_expires_at,
      session: value.session,
      user: auth.user,
    },
    false
  )
}

export function clearAuthentication(
  synchronizeTabs = true,
  bootstrapState: AuthBootstrapState = 'complete'
): void {

View on GitHub (pinned to e2c7aa7b10)

Solutions

  1. If the store's sid is stale (another tab logged in fresh), the cross-tab authenticated event should have replaced the bundle — verify publishAuthSessionEvent handling and tab synchronization.
  2. Tag refresh requests with the current sid and have the server reject rotations for superseded sessions, so mismatches become explicit 401s instead of client-side throws.
  3. On this error, force a full re-bootstrap (bootstrapAuthentication) or redirect to sign-in; do not retry the same rotation blindly.
Defensive patterns

Strategy: validation

Validate before calling

const currentSid = useAuthStore.getState().auth.session?.sid
if (value.session.sid !== currentSid) {
  // stale or foreign session: re-bootstrap instead of applying
  await bootstrapAuthentication()
  return
}

Try / catch

try {
  applyAuthRotation(value)
} catch (error) {
  if (error instanceof AuthRotationError && /session mismatch/i.test(error.message)) {
    await bootstrapAuthentication() // adopt whichever session is authoritative
    return
  }
  throw error
}

Prevention

When it happens

Trigger: Rotation endpoint returns credentials bound to a different sid than auth.session.sid: the same account re-authenticated in another tab creating a new session, server-side session regeneration, or a duplicated/stale refresh response replayed after re-login.

Common situations: Two tabs sharing localStorage where one re-logs-in and changes the session while the other's rotation is in flight; backend regenerating sessions on privilege change; a queued retry of an old refresh response after the store already holds a new session.

Understand the failure class

Related errors


AI-assisted analysis of QuantumNous/new-api@e2c7aa7b10 (2026-08-15). Data as JSON: /api/errors/4492f25aab7994e6. Report an issue: GitHub.