chatboxai/chatbox · error · Error

MiniMax OAuth failed: ${errorMessage || text}

Error message

MiniMax OAuth failed: ${errorMessage || text}

What it means

Thrown inside MiniMax's waitForToken() polling loop when either the HTTP response is not ok, or getMiniMaxErrorMessage() returned a non-undefined message (which happens when payload.status==='error' or base_resp.status_code is non-zero). Unlike GitHub, MiniMax signals terminal errors through status fields in a 200 body, so this single guard covers both transport failures and application-level denials.

Source

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

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

          if (response.ok && payload.access_token) {
            return {
              accessToken: payload.access_token,
              refreshToken: payload.refresh_token,
              expiresAt: toExpiresAt(payload.expired_in),
            }
          }

          const errorMessage = getMiniMaxErrorMessage(payload, text)
          if (!response.ok || errorMessage) {
            throw new Error(`MiniMax OAuth failed: ${errorMessage || text}`)
          }

          intervalMs = Math.min(Math.round(intervalMs * 1.5), 10_000)
        }

        throw new Error('MiniMax OAuth timed out waiting for authorization.')
      } finally {
        pendingUserCode = null
        pendingVerifier = null
        pendingIntervalMs = 2000
      }
    },

    async refreshToken(credentials) {
      if (!credentials.refreshToken) {
        return credentials
      }

View on GitHub (pinned to 81571269ad)

Solutions

  1. Read the interpolated errorMessage — MiniMax's base_resp.status_msg usually says exactly what went wrong (e.g. 'expired', 'invalid code').
  2. For 'expired' or 'invalid code' errors, restart with startDeviceFlow() to get a new user_code.
  3. For transient non-ok responses, retry once before surfacing.
  4. Distinguish status==='error' (terminal, restart) from status==='pending' (the helper suppresses pending so it should never reach here).

Example fix

// before
throw new Error(`MiniMax OAuth failed: ${errorMessage || text}`)

// after
if (/expir|invalid|denied/i.test(errorMessage || '')) {
  throw new ReauthRequiredError(`MiniMax code invalid or expired: ${errorMessage}`)
}
throw new Error(`MiniMax OAuth failed: ${errorMessage || text}`)
Defensive patterns

Strategy: try-catch

Type guard

function isMiniMaxTerminalMessage(msg: string): boolean {
  return /expir|invalid|denied|revok|suspend|quota/i.test(msg)
}

Try / catch

try {
  return await provider.waitForToken(signal)
} catch (e) {
  const msg = String(e)
  if (/MiniMax OAuth failed/i.test(msg)) {
  if (/expir|invalid|denied/i.test(msg)) {
  const fresh = await provider.startDeviceFlow()
  throw new ReauthRequiredError(fresh)
  }
  if (/5\d\d|network|fetch/i.test(msg)) return await provider.waitForToken(signal)
  }
  throw e
}

Prevention

When it happens

Trigger: payload.status==='error' with a base_resp.status_msg (denied, invalid user_code, expired code); non-2xx HTTP from /oauth/token (network, 5xx); base_resp.status_code non-zero indicating a business error like 'code used' or 'verification failed'.

Common situations: User entered the wrong user_code at MiniMax and verification failed; user_code expired while polling; MiniMax returned a 5xx mid-poll; the user denied consent.

Related errors


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