{"record":{"id":"8fb272236a58dc92","repo":"can1357/oh-my-pi","slug":"kimi-token-refresh-failed-response-status-des","errorCode":null,"errorMessage":"Kimi token refresh failed: ${response.status}${description}","messagePattern":"Kimi token refresh failed: (.+?)(.+?)","errorType":"exception","errorClass":"AIError.OAuthError","httpStatus":null,"severity":"error","filePath":"packages/ai/src/registry/oauth/kimi.ts","lineNumber":308,"sourceCode":" */\nexport async function refreshKimiToken(refreshToken: string): Promise<OAuthCredentials> {\n\tconst response = await fetch(`${resolveOAuthHost()}/api/oauth/token`, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t...getKimiCommonHeaders(),\n\t\t},\n\t\tbody: new URLSearchParams({\n\t\t\tgrant_type: \"refresh_token\",\n\t\t\trefresh_token: refreshToken,\n\t\t\tclient_id: CLIENT_ID,\n\t\t}),\n\t});\n\n\tif (!response.ok) {\n\t\tconst payload = (await response.json().catch(() => undefined)) as TokenResponse | undefined;\n\t\tconst description = payload?.error_description ? `: ${payload.error_description}` : \"\";\n\t\tthrow new AIError.OAuthError(`Kimi token refresh failed: ${response.status}${description}`, {\n\t\t\tkind: \"token-refresh\",\n\t\t\tprovider: \"kimi\",\n\t\t\tstatus: response.status,\n\t\t});\n\t}\n\n\tconst payload = (await response.json()) as TokenResponse;\n\treturn parseTokenPayload(payload, refreshToken);\n}\n","sourceCodeStart":290,"sourceCodeEnd":318,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/ai/src/registry/oauth/kimi.ts#L290-L318","documentation":"Thrown by refreshKimiToken when the OAuth token refresh POST to Kimi returns a non-ok HTTP status. The error includes the HTTP status and any error_description Kimi returned, and is classified kind='token-refresh' with the status attached. It means the stored refresh token could not be exchanged for a new access token.","triggerScenarios":"The stored refresh token is expired or revoked (Kimi refresh tokens have limited lifetimes); the refresh token was invalidated because the user logged out elsewhere or re-authorized; Kimi returns 400/401 for a malformed or unknown refresh_token; transient 5xx from Kimi's token endpoint.","commonSituations":"Long-lived sessions where the refresh token expired; user revoking the app in Kimi account settings; copying auth state between machines so tokens mismatch; Kimi rotating client credentials in a CLI update making old grants invalid.","solutions":["Re-run the Kimi login flow (loginKimi()) to obtain fresh access/refresh tokens","Clear cached Kimi credentials for this tool before re-authenticating to avoid stale tokens","Check the embedded HTTP status: 400/401 means the refresh token is bad (must re-login); 5xx means retry later","Update the CLI if Kimi changed its OAuth client configuration"],"exampleFix":"// before: assume refresh always works\nconst session = await getKimiSession();\n// after: fall back to full re-login on refresh failure\nlet session;\ntry {\n  session = await refreshKimiToken(stored.refresh);\n} catch (e) {\n  if (e instanceof AIError.OAuthError && e.kind === 'token-refresh') {\n    session = await loginKimi();\n  } else throw e;\n}","handlingStrategy":"try-catch","validationCode":"// before calling, check the stored refresh token is present and not obviously stale\nif (!stored?.refresh || Date.now() > stored.expires + 30 * 24 * 3600 * 1000) {\n  await loginKimi(); // refresh token likely expired/revoked — re-auth up front\n}","typeGuard":null,"tryCatchPattern":"try {\n  session = await refreshKimiToken(stored.refresh);\n} catch (e) {\n  if (e instanceof AIError.OAuthError && e.kind === 'token-refresh') {\n    if (e.status && e.status >= 500) {\n      // transient: back off and retry the refresh\n    } else {\n      session = await loginKimi(); // 4xx: full re-auth required\n    }\n  } else throw e;\n}","preventionTips":["Re-authenticate proactively when refresh tokens near expiry","Don't share/copy credential caches between machines","Catch token-refresh errors and fall back to interactive login instead of crashing","After revoking access in Kimi settings, expect to re-login"],"tags":["oauth","kimi","token-refresh","http-error"],"backgroundTag":"oauth-token-refresh-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}