{"record":{"id":"699f6a254de21b5d","repo":"chatboxai/chatbox","slug":"minimax-authorization-failed-text","errorCode":null,"errorMessage":"MiniMax authorization failed: ${text}","messagePattern":"MiniMax authorization failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/oauth/providers/minimax.ts","lineNumber":109,"sourceCode":"        method: 'POST',\n        headers: {\n          Accept: 'application/json',\n          'Content-Type': 'application/x-www-form-urlencoded',\n          'x-request-id': randomUUID(),\n        },\n        body: new URLSearchParams({\n          response_type: 'code',\n          client_id: MINIMAX_CLIENT_ID,\n          scope: 'group_id profile model.completion',\n          code_challenge: challenge,\n          code_challenge_method: 'S256',\n          state,\n        }).toString(),\n      })\n\n      if (!response.ok) {\n        const text = await response.text()\n        throw new Error(`MiniMax authorization failed: ${text}`)\n      }\n\n      const payload = (await response.json()) as {\n        user_code: string\n        verification_uri: string\n        expired_in?: number\n        interval?: number\n        state: string\n      }\n\n      if (payload.state !== state) {\n        throw new Error('MiniMax OAuth state mismatch')\n      }\n\n      pendingUserCode = payload.user_code\n      pendingVerifier = verifier\n      pendingIntervalMs = toPollingIntervalMs(payload.interval)\n","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/chatboxai/chatbox/blob/81571269addb6bafb589a920b2883f1e1e084fd1/src/main/oauth/providers/minimax.ts#L91-L127","documentation":"Thrown by MiniMax's startDeviceFlow() when the initial POST to {baseUrl}/oauth/code returns non-2xx. The raw response body is interpolated, exposing MiniMax's reason. This is the very first call that registers the device flow and obtains the user_code, so failure here means the polling stage is never reached.","triggerScenarios":"Wrong baseUrl for the chosen provider variant (api.minimax.io vs api.minimaxi.com for CN); MINIMAX_CLIENT_ID rejected; requested scope (group_id profile model.completion) not permitted for the client; malformed code_challenge; request-id header rejected; MiniMax API outage or rate limit.","commonSituations":"User selected MiniMax CN but the global baseUrl is hit (or vice-versa); MINIMAX_CLIENT_ID constant drifted after a server-side rotation; PKCE challenge not S256-compatible; corporate firewall rewriting the form body.","solutions":["Match the baseUrl to the provider variant — Global uses api.minimax.io, CN uses api.minimaxi.com.","Verify MINIMAX_CLIENT_ID and that the scope string matches what MiniMax registered for the client.","Read the interpolated body for MiniMax's status_msg; 4xx usually means client/scope mismatch, 5xx means retry.","Confirm code_challenge_method is 'S256' and the challenge is the base64url SHA-256 of the verifier."],"exampleFix":"// before\nconst response = await fetch(`${config.baseUrl}/oauth/code`, init)\nif (!response.ok) {\n  const text = await response.text()\n  throw new Error(`MiniMax authorization failed: ${text}`)\n}\n\n// after\nif (!response.ok) {\n  const text = await response.text()\n  log.error('[OAuth:MiniMax] device code request failed', response.status, text)\n  if (response.status >= 500) throw new TransientError('MiniMax unavailable, retry')\n  throw new Error(`MiniMax authorization failed (${response.status}): ${text}`)\n}","handlingStrategy":"try-catch","validationCode":"// Confirm the provider variant matches its base URL before starting.\nfunction assertMiniMaxVariant(providerId: string, baseUrl: string) {\n  if (providerId === 'minimax' && !baseUrl.includes('api.minimax.io')) throw new Error('Global MiniMax must use api.minimax.io')\n  if (providerId === 'minimax-cn' && !baseUrl.includes('api.minimaxi.com')) throw new Error('CN MiniMax must use api.minimaxi.com')\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await provider.startDeviceFlow()\n} catch (e) {\n  const msg = String(e)\n  if (/MiniMax authorization failed/i.test(msg)) {\n  if (/5\\d\\d|network|fetch/i.test(msg)) return await provider.startDeviceFlow() // transient retry\n  throw new Error('MiniMax rejected the device request — check client_id, scope, and baseUrl.')\n  }\n  throw e\n}","preventionTips":["Match baseUrl to the provider variant: Global=api.minimax.io, CN=api.minimaxi.com.","Keep MINIMAX_CLIENT_ID and the scope string in sync with the MiniMax app registration.","Generate the PKCE challenge as base64url SHA-256 of the verifier with method S256."],"tags":["oauth","network","minimax","device-flow","pkce"],"backgroundTag":null,"analyzedSha":"81571269addb6bafb589a920b2883f1e1e084fd1","analyzedAt":"2026-08-12T21:51:44.981Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}