QuantumNous/new-api · error · AuthRotationError

Invalid authentication rotation response

Error message

Invalid authentication rotation response

What it means

Thrown by applyAuthRotation in the auth session module when a payload delivered to rotate the access token fails the isAuthTokenRotation structural check (missing/malformed access_token, session, expiry, or token_type fields). It guards the store against installing a corrupt rotation payload that would break every subsequent authenticated request.

Source

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

    value.session.current
  )
}

export function applyAuthBundle(
  bundle: AuthBundle,
  synchronizeTabs = true
): void {
  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,
    },

View on GitHub (pinned to e2c7aa7b10)

Solutions

  1. Log the actual value passed to applyAuthRotation (never in production output) and diff it against the expected fields: access_token, token_type, access_expires_at, session.sid.
  2. Check the backend rotation endpoint's response schema and align isAuthTokenRotation with it after any backend upgrade.
  3. Ensure the fetch wrapper rejects non-JSON responses (check content-type) before the rotation path sees them.
  4. After the throw, force re-authentication — the rotation is skipped and the old token remains, so redirect to sign-in rather than retrying in a loop.
Defensive patterns

Strategy: type-guard

Type guard

// isAuthTokenRotation already exists; reuse it before calling applyAuthRotation
import { isAuthTokenRotation } from '@/lib/auth-session'
if (!isAuthTokenRotation(payload)) {
  // force re-login instead of letting AuthRotationError propagate
}

Try / catch

try {
  applyAuthRotation(payload)
} catch (error) {
  if (error instanceof AuthRotationError) {
    // clear auth state and redirect to /sign-in; do not retry with the same payload
  }
  throw error
}

Prevention

When it happens

Trigger: An auth rotation response (token refresh path) arrives that is not shaped like an AuthTokenRotation: missing access_token, missing session.sid, non-numeric access_expires_at, or the payload is null/an error envelope that leaked into the rotation channel.

Common situations: Backend version change altering the rotation response shape; a proxy returning an HTML error page parsed as JSON; interceptor accidentally forwarding an error body to applyAuthRotation; race where a logout response is mistaken for rotation.

Understand the failure class

Related errors


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