{"record":{"id":"9e792f47699e6344","repo":"chatboxai/chatbox","slug":"minimax-oauth-failed-errormessage-text","errorCode":null,"errorMessage":"MiniMax OAuth failed: ${errorMessage || text}","messagePattern":"MiniMax OAuth failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/oauth/providers/minimax.ts","lineNumber":182,"sourceCode":"          const payload = JSON.parse(text || '{}') as {\n            status?: string\n            access_token?: string\n            refresh_token?: string\n            expired_in?: number\n            base_resp?: { status_code?: number; status_msg?: string }\n          }\n\n          if (response.ok && payload.access_token) {\n            return {\n              accessToken: payload.access_token,\n              refreshToken: payload.refresh_token,\n              expiresAt: toExpiresAt(payload.expired_in),\n            }\n          }\n\n          const errorMessage = getMiniMaxErrorMessage(payload, text)\n          if (!response.ok || errorMessage) {\n            throw new Error(`MiniMax OAuth failed: ${errorMessage || text}`)\n          }\n\n          intervalMs = Math.min(Math.round(intervalMs * 1.5), 10_000)\n        }\n\n        throw new Error('MiniMax OAuth timed out waiting for authorization.')\n      } finally {\n        pendingUserCode = null\n        pendingVerifier = null\n        pendingIntervalMs = 2000\n      }\n    },\n\n    async refreshToken(credentials) {\n      if (!credentials.refreshToken) {\n        return credentials\n      }\n","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/chatboxai/chatbox/blob/81571269addb6bafb589a920b2883f1e1e084fd1/src/main/oauth/providers/minimax.ts#L164-L200","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","solutions":["Read the interpolated errorMessage — MiniMax's base_resp.status_msg usually says exactly what went wrong (e.g. 'expired', 'invalid code').","For 'expired' or 'invalid code' errors, restart with startDeviceFlow() to get a new user_code.","For transient non-ok responses, retry once before surfacing.","Distinguish status==='error' (terminal, restart) from status==='pending' (the helper suppresses pending so it should never reach here)."],"exampleFix":"// before\nthrow new Error(`MiniMax OAuth failed: ${errorMessage || text}`)\n\n// after\nif (/expir|invalid|denied/i.test(errorMessage || '')) {\n  throw new ReauthRequiredError(`MiniMax code invalid or expired: ${errorMessage}`)\n}\nthrow new Error(`MiniMax OAuth failed: ${errorMessage || text}`)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isMiniMaxTerminalMessage(msg: string): boolean {\n  return /expir|invalid|denied|revok|suspend|quota/i.test(msg)\n}","tryCatchPattern":"try {\n  return await provider.waitForToken(signal)\n} catch (e) {\n  const msg = String(e)\n  if (/MiniMax OAuth failed/i.test(msg)) {\n  if (/expir|invalid|denied/i.test(msg)) {\n  const fresh = await provider.startDeviceFlow()\n  throw new ReauthRequiredError(fresh)\n  }\n  if (/5\\d\\d|network|fetch/i.test(msg)) return await provider.waitForToken(signal)\n  }\n  throw e\n}","preventionTips":["Read base_resp.status_msg to distinguish 'expired/invalid' (restart) from transient failures (retry).","Make sure the user enters the user_code exactly as shown at the verification_uri.","Complete authorization promptly to avoid mid-poll expiry."],"tags":["oauth","minimax","device-flow","application-error"],"backgroundTag":null,"analyzedSha":"81571269addb6bafb589a920b2883f1e1e084fd1","analyzedAt":"2026-08-12T21:51:44.981Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}