{"record":{"id":"e12d23b111a9d691","repo":"decolua/9router","slug":"access-token-is-required","errorCode":null,"errorMessage":"access_token is required","messagePattern":"access_token is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/lib/oauth/kiroExternalIdp.js","lineNumber":104,"sourceCode":"\n  if (!input || typeof input !== \"object\") {\n    throw new Error(\"CLIProxyAPI auth JSON is required\");\n  }\n\n  const authMethod = normalizeString(input.auth_method || input.authMethod);\n  if (authMethod && authMethod !== \"external_idp\") {\n    throw new Error(\"Only external_idp Kiro auth is supported by this importer\");\n  }\n\n  const accessToken = normalizeString(input.access_token || input.accessToken);\n  const refreshToken = normalizeString(input.refresh_token || input.refreshToken);\n  const clientId = normalizeString(input.client_id || input.clientId);\n  const tokenEndpoint = validateMicrosoftTokenEndpoint(input.token_endpoint || input.tokenEndpoint);\n  const profileArn = normalizeString(input.profile_arn || input.profileArn);\n  const region = normalizeString(input.region) || DEFAULT_REGION;\n  const scope = normalizeScope(input.scopes || input.scope);\n\n  if (!accessToken) throw new Error(\"access_token is required\");\n  if (!refreshToken) throw new Error(\"refresh_token is required\");\n  if (!clientId) throw new Error(\"client_id is required\");\n  if (!scope) throw new Error(\"scopes is required\");\n  if (!profileArn) throw new Error(\"profile_arn is required\");\n\n  const payload = decodeJwtPayload(accessToken);\n  const email = input.email || payload?.email || payload?.preferred_username || payload?.upn || payload?.sub || null;\n\n  return {\n    accessToken,\n    refreshToken,\n    expiresAt: resolveExpiresAt(input),\n    email,\n    providerSpecificData: {\n      profileArn,\n      region,\n      authMethod: \"external_idp\",\n      provider: \"CLIProxyAPI\",","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/lib/oauth/kiroExternalIdp.js#L86-L122","documentation":"normalizeKiroExternalIdpAuth requires a non-empty access_token (snake_case or camelCase accepted) in the auth document. The access token is the primary Kiro credential and is needed to decode the JWT payload for email/expiry. An empty or missing token aborts the import.","triggerScenarios":"Auth JSON lacking access_token/accessToken, or where the value is an empty string or whitespace; copying a template file with placeholder fields left blank.","commonSituations":"Hand-authored auth JSON missing the token; a partially-written auth file from a failed login; the wrong file imported (e.g. a config file that shares the auth document's shape but no tokens).","solutions":["Add the access_token (or accessToken) field with the actual Kiro access token JWT","Re-run the external IdP login to obtain a fresh auth document containing access_token","Verify you imported the auth JSON, not a settings/config file","Check for key-name typos — the importer accepts access_token and accessToken only"],"exampleFix":"// before\n{ \"client_id\": \"...\", \"refresh_token\": \"...\", \"scopes\": \"openid\" }\n// after\n{ \"access_token\": \"eyJhbGciOi...\", \"client_id\": \"...\", \"refresh_token\": \"...\", \"scopes\": \"openid\" }","handlingStrategy":"validation","validationCode":"function hasNonEmpty(v, ...keys) { return keys.some(k => typeof v?.[k] === 'string' && v[k].trim()); }\nif (!hasNonEmpty(auth, 'access_token', 'accessToken')) throw new Error('access_token missing from Kiro auth');","typeGuard":"function hasAccessToken(a) {\n  return typeof a === 'object' && a !== null &&\n    ['access_token', 'accessToken'].some(k => typeof a[k] === 'string' && a[k].trim() !== '');\n}","tryCatchPattern":"try {\n  normalizeKiroExternalIdpAuth(auth);\n} catch (e) {\n  if (e.message === 'access_token is required') {\n    console.error('Auth document has no access_token; re-run the login flow');\n  }\n  throw e;\n}","preventionTips":["Validate all required fields (access_token, refresh_token, client_id, scopes, profile_arn) with one pre-flight check before import","Import the real auth file, not templates or config files","Accept both snake_case and camelCase in your own checks to match the importer","Re-authenticate rather than importing token-less partial documents"],"tags":["oauth","missing-field","access-token","validation"],"backgroundTag":"missing-required-field","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}