chatboxai/chatbox · critical · Error

Failed to refresh token: missing tokens in response headers

Error message

Failed to refresh token: missing tokens in response headers

What it means

Thrown by the token-refresh routine when the refresh response is missing the x-chatbox-access-token or x-chatbox-refresh-token response header. The app exchanges a refresh token for a new token pair via custom headers (not the JSON body), so absent headers mean the refresh contract broke. A log line records which header is missing.

Source

Thrown at src/renderer/packages/remote.ts:960

      },
    },
    {
      parseChatboxRemoteError: true,
      retry: 2,
    }
  )
  const json: Response = await res.json()
  // log.info('✅ refreshAccessToken response', json)

  const accessToken = res.headers.get('x-chatbox-access-token')
  const refreshToken = res.headers.get('x-chatbox-refresh-token')

  if (!accessToken || !refreshToken) {
    log.error('❌ Missing tokens in response headers:', {
      accessToken: accessToken ? 'present' : 'missing',
      refreshToken: refreshToken ? 'present' : 'missing',
    })
    throw new Error('Failed to refresh token: missing tokens in response headers')
  }

  return {
    accessToken,
    refreshToken,
  }
}

export async function getUserProfile() {
  type Response = {
    data: {
      email: string
      id: string
      created_at: string
    }
  }
  const afetch = await getAuthenticatedAfetch()
  const res = await afetch(

View on GitHub (pinned to 81571269ad)

Solutions

  1. Check the server log/error to confirm the refresh endpoint is issuing both headers.
  2. If behind a proxy/CDN, ensure x-chatbox-* headers are passed through and exposed via CORS (Access-Control-Expose-Headers).
  3. Verify the user's refresh token is still valid — a revoked session may yield a tokenless success.
  4. Confirm backend/header contract version matches the client.
Defensive patterns

Strategy: retry

Validate before calling

// cannot fully validate headers pre-call, but ensure session is fresh:
if (!authInfoStore.getState().refreshToken) {
  // force re-login instead of attempting refresh
}

Type guard

function hasTokenHeaders(res: Response): boolean {
  return !!res.headers.get('x-chatbox-access-token') && !!res.headers.get('x-chatbox-refresh-token')
}

Try / catch

try {
  await refreshAccessToken()
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Failed to refresh token: missing tokens')) {
    // force re-authentication; clear stale refresh token
  }
}

Prevention

When it happens

Trigger: The refresh endpoint returns 2xx but without the expected x-chatbox-access-token / x-chatbox-refresh-token headers. Triggered whenever either header is null after `res.headers.get(...)`.

Common situations: A proxy/CDN strips custom x- headers; the backend deployed a change that moved tokens into the body or renamed headers; CORS exposure policy hides custom headers from the browser; a session expired server-side and the endpoint returned success without tokens.

Related errors


AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12). Data as JSON: /api/errors/5f83e2bdfa3c896f. Report an issue: GitHub.