{"record":{"id":"bb5a50d22ab3cea8","repo":"musistudio/claude-code-router","slug":"kimi-cli-refresh-token-was-not-found","errorCode":null,"errorMessage":"Kimi CLI refresh token was not found.","messagePattern":"Kimi CLI refresh token was not found\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/agents/local-providers/kimi.ts","lineNumber":399,"sourceCode":"  return {\n    key: configured.oauthKey,\n    ...(configured.oauthHost ? { oauthHost: configured.oauthHost } : {})\n  };\n}\n\nfunction findKimiOauthProvider(reference?: KimiOauthReference): KimiConfiguredProvider | undefined {\n  const configured = readKimiConfiguredProviders().filter((item) => Boolean(item.oauthKey && !item.apiKey));\n  const key = reference?.key?.trim();\n  if (!key) return configured[0];\n  const oauthHost = reference?.oauthHost?.trim().replace(/\\/+$/, \"\");\n  return configured.find((item) =>\n    item.oauthKey === key && (!oauthHost || item.oauthHost?.replace(/\\/+$/, \"\") === oauthHost)\n  ) ?? configured.find((item) => item.oauthKey === key);\n}\n\nasync function refreshKimiAuth(auth: KimiTokenSet): Promise<KimiTokenSet> {\n  if (!auth.refreshToken) {\n    throw new Error(\"Kimi CLI refresh token was not found.\");\n  }\n  const controller = new AbortController();\n  const timer = setTimeout(() => controller.abort(), kimiOauthRefreshTimeoutMs);\n  const oauthHost = (auth.oauthHost || kimiOauthHost).replace(/\\/+$/, \"\");\n  try {\n    const response = await fetchWithSystemProxy(`${oauthHost}/api/oauth/token`, {\n      body: new URLSearchParams({\n        client_id: kimiOauthClientId,\n        grant_type: \"refresh_token\",\n        refresh_token: auth.refreshToken\n      }).toString(),\n      headers: {\n        ...withoutHeader(kimiIdentityHeaders(), \"user-agent\"),\n        accept: \"application/json\",\n        \"content-type\": \"application/x-www-form-urlencoded\"\n      },\n      method: \"POST\",\n      signal: controller.signal","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/core/src/agents/local-providers/kimi.ts#L381-L417","documentation":"refreshKimiAuth requires a refresh token to mint a new access token, but the stored KimiTokenSet has an empty/absent refreshToken. Without it the OAuth refresh grant cannot even be attempted, so the error is thrown before any network call.","triggerScenarios":"resolveKimiAuth decides the access token is expired and calls refreshKimiAuth, but the persisted token set was created from a flow that never issued a refresh token, or the field was lost/cleared in config.","commonSituations":"API-key-based setups that later switched to OAuth with a partial token set; config migration dropped the refresh_token field; the provider issued only short-lived tokens without offline_access scope.","solutions":["Re-run the full kimi OAuth login to obtain a token set that includes a refresh token","Inspect the stored credentials file to confirm refresh_token is present and non-empty","If the provider no longer issues refresh tokens, fall back to API key authentication","Ensure the login flow requests offline access scope"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const auth = await resolveKimiAuth(ref).catch(() => undefined);\nif (auth && kimiAccessTokenExpired(auth) && !auth.refreshToken) {\n  await kimiLogin(); // cannot refresh, must re-auth\n}","typeGuard":"function canRefreshKimi(auth: KimiTokenSet): boolean {\n  return typeof auth.refreshToken === 'string' && auth.refreshToken.length > 0;\n}","tryCatchPattern":"catch (e) {\n  if (e instanceof Error && e.message === 'Kimi CLI refresh token was not found.') {\n    await kimiLogin(); // no retry path exists\n  }\n}","preventionTips":["Require offline-access scope at login so refresh tokens are issued","Validate token sets contain refreshToken before persisting","Fall back to API key auth when no refresh token is available"],"tags":["kimi","oauth","refresh-token","authentication"],"backgroundTag":"oauth-refresh-token-missing","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}