chatboxai/chatbox · error · Error

Token refresh failed: ${text}

Error message

Token refresh failed: ${text}

What it means

Thrown by MiniMax's refreshToken() when the POST to {baseUrl}/oauth/token returns non-2xx. The raw response text is interpolated and logged. This is the transport-level refresh failure; a separate guard (error 72) handles the case where HTTP is 200 but the business status is not 'success'.

Source

Thrown at src/main/oauth/providers/minimax.ts:217

      }

      const response = await fetch(`${config.baseUrl}/oauth/token`, {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: new URLSearchParams({
          grant_type: 'refresh_token',
          client_id: MINIMAX_CLIENT_ID,
          refresh_token: credentials.refreshToken,
        }).toString(),
      })

      const text = await response.text()
      if (!response.ok) {
        log.error(`[OAuth:${config.name}] Token refresh failed:`, text)
        throw new Error(`Token refresh failed: ${text}`)
      }

      const payload = JSON.parse(text || '{}') as {
        status?: string
        access_token?: string
        refresh_token?: string
        expired_in?: number
        base_resp?: { status_msg?: string }
      }

      if (payload.status !== 'success' || !payload.access_token) {
        throw new Error(`Token refresh failed: ${payload.base_resp?.status_msg || text}`)
      }

      return {
        accessToken: payload.access_token,
        refreshToken: payload.refresh_token || credentials.refreshToken,
        expiresAt: toExpiresAt(payload.expired_in),

View on GitHub (pinned to 81571269ad)

Solutions

  1. On 4xx with revocation language, clear stored credentials and trigger an interactive startDeviceFlow() login.
  2. On 5xx or network error, retry once with backoff.
  3. Verify baseUrl matches the provider variant (api.minimax.io vs api.minimaxi.com).
  4. Serialize refresh calls per account to avoid rotation races.

Example fix

// before
if (!response.ok) {
  const text = await response.text()
  throw new Error(`Token refresh failed: ${text}`)
}

// after
if (!response.ok) {
  const text = await response.text()
  if (response.status >= 500) throw new TransientError('MiniMax refresh transient')
  if (response.status === 400 || response.status === 401) {
    throw new ReauthRequiredError('MiniMax refresh token invalid — re-login required')
  }
  throw new Error(`Token refresh failed (${response.status}): ${text}`)
}
Defensive patterns

Strategy: try-catch

Validate before calling

function assertMiniMaxVariantForRefresh(providerId: string, baseUrl: string) {
  if (providerId === 'minimax' && !baseUrl.includes('api.minimax.io')) throw new Error('Global MiniMax must use api.minimax.io')
  if (providerId === 'minimax-cn' && !baseUrl.includes('api.minimaxi.com')) throw new Error('CN MiniMax must use api.minimaxi.com')
}

Try / catch

try {
  return await provider.refreshToken(credentials)
} catch (e) {
  const msg = String(e)
  if (/Token refresh failed/i.test(msg)) {
  if (/5\d\d|network|fetch/i.test(msg)) return await provider.refreshToken(credentials)
  // 4xx: refresh token dead — force re-login
  await clearStoredCredentials()
  throw new ReauthRequiredError(msg)
  }
  throw e
}

Prevention

When it happens

Trigger: Refresh token revoked or expired (MiniMax returns 4xx); wrong baseUrl for the provider variant; MINIMAX_CLIENT_ID mismatch; network failure / 5xx; concurrent refresh calls invalidating the token.

Common situations: Long-idle user whose MiniMax grant expired; selected CN provider but global endpoint was hit (or vice-versa); a parallel refresh on another device rotated the token.

Related errors


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