decolua/9router · error

CLIProxyAPI auth JSON is invalid

Error message

CLIProxyAPI auth JSON is invalid

What it means

normalizeKiroExternalIdpAuth accepts either an object or a JSON string for the Kiro CLIProxyAPI auth. When a string is passed, JSON.parse must succeed; a parse failure means the auth blob is malformed and this error is thrown. The importer cannot proceed without a parseable auth document.

Source

Thrown at src/lib/oauth/kiroExternalIdp.js:83

  if (Number.isFinite(expiresIn) && expiresIn > 0) {
    return new Date(Date.now() + expiresIn * 1000).toISOString();
  }

  const payload = decodeJwtPayload(input.access_token || input.accessToken);
  if (payload?.exp) {
    return new Date(payload.exp * 1000).toISOString();
  }

  return new Date(Date.now() + DEFAULT_EXPIRES_IN * 1000).toISOString();
}

export function normalizeKiroExternalIdpAuth(rawAuth) {
  let input = rawAuth;
  if (typeof input === "string") {
    try {
      input = JSON.parse(input);
    } catch {
      throw new Error("CLIProxyAPI auth JSON is invalid");
    }
  }

  if (!input || typeof input !== "object") {
    throw new Error("CLIProxyAPI auth JSON is required");
  }

  const authMethod = normalizeString(input.auth_method || input.authMethod);
  if (authMethod && authMethod !== "external_idp") {
    throw new Error("Only external_idp Kiro auth is supported by this importer");
  }

  const accessToken = normalizeString(input.access_token || input.accessToken);
  const refreshToken = normalizeString(input.refresh_token || input.refreshToken);
  const clientId = normalizeString(input.client_id || input.clientId);
  const tokenEndpoint = validateMicrosoftTokenEndpoint(input.token_endpoint || input.tokenEndpoint);
  const profileArn = normalizeString(input.profile_arn || input.profileArn);
  const region = normalizeString(input.region) || DEFAULT_REGION;

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Validate the string with JSON.parse locally before calling, and print JSON.parse(err).message to see the exact syntax error position
  2. Re-export or re-copy the CLIProxyAPI auth file and confirm it starts with '{' and is complete
  3. If the value came from a file read, strip a UTF-8 BOM and read as UTF-8 before parsing
  4. If you actually hold a non-JSON token, wrap it in the expected auth object shape and pass the object instead of a string

Example fix

// before
normalizeKiroExternalIdpAuth(fs.readFileSync(authPath, 'utf8'))
// after
const raw = fs.readFileSync(authPath, 'utf8').replace(/^\uFEFF/, '').trim();
const auth = JSON.parse(raw); // throws a precise SyntaxError if malformed
normalizeKiroExternalIdpAuth(auth);
Defensive patterns

Strategy: validation

Validate before calling

function safeParseAuthJson(raw) {
  if (typeof raw !== 'string') return raw;
  try { return JSON.parse(raw.replace(/^\uFEFF/, '').trim()); }
  catch (e) { throw new Error(`Kiro auth JSON parse failed: ${e.message}`); }
}
const input = safeParseAuthJson(rawAuth);

Type guard

function isParseableObject(v) {
  if (typeof v !== 'string') return v !== null && typeof v === 'object';
  try { return JSON.parse(v) !== null && typeof JSON.parse(v) === 'object'; } catch { return false; }
}

Try / catch

try {
  normalizeKiroExternalIdpAuth(rawAuth);
} catch (e) {
  if (e.message === 'CLIProxyAPI auth JSON is invalid') {
    console.error('Auth file is not valid JSON; re-export it from CLIProxyAPI');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling normalizeKiroExternalIdpAuth(rawAuth) with a string argument that is not valid JSON — e.g. truncated file contents, single-quoted keys, trailing commas, a raw JWT pasted instead of the auth JSON, or a file read that returned garbage/BOM-prefixed text.

Common situations: Pasting the content of a CLIProxyAPI auth file with copy/paste truncation; importing an auth file edited by hand and left syntactically invalid; passing a token string instead of the full auth JSON; reading the file with the wrong encoding (UTF-16) so the parser sees stray bytes.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/f19228b005c8391f. Report an issue: GitHub.