{"record":{"id":"fca60860c1069c0d","repo":"google-gemini/gemini-cli","slug":"failed-to-parse-inline-agent-card-json-for-agent","errorCode":null,"errorMessage":"Failed to parse inline agent card JSON for agent '${name}': ${msg}","messagePattern":"Failed to parse inline agent card JSON for agent '(.+?)': (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/agents/a2a-client-manager.ts","lineNumber":132,"sourceCode":"      // Retry with auth if we hit a 401/403\n      if ((response.status === 401 || response.status === 403) && authFetch) {\n        return authFetch(input, init);\n      }\n\n      return response;\n    };\n\n    const resolver = new DefaultAgentCardResolver({ fetchImpl: cardFetch });\n\n    let rawCard: unknown;\n    let urlIdentifier = 'inline JSON';\n\n    if (options.type === 'json') {\n      try {\n        rawCard = JSON.parse(options.json);\n      } catch (error) {\n        const msg = error instanceof Error ? error.message : String(error);\n        throw new Error(\n          `Failed to parse inline agent card JSON for agent '${name}': ${msg}`,\n        );\n      }\n    } else {\n      urlIdentifier = options.url;\n      rawCard = await resolver.resolve(options.url, '');\n    }\n\n    // TODO: Remove normalizeAgentCard once @a2a-js/sdk handles\n    // proto field name aliases (supportedInterfaces → additionalInterfaces,\n    // protocolBinding → transport).\n    const agentCard = normalizeAgentCard(rawCard);\n\n    const grpcUrl =\n      agentCard.additionalInterfaces?.find((i) => i.transport === 'GRPC')\n        ?.url ?? agentCard.url;\n\n    const clientOptions = ClientFactoryOptions.createFrom(","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/core/src/agents/a2a-client-manager.ts#L114-L150","documentation":"Thrown when an inline agent card supplied via `{ type: 'json', json: '...' }` fails to parse. The manager wraps `JSON.parse` in a try/catch; any SyntaxError (or non-Error throw) is re-thrown with the agent name and the underlying parse message so the caller can see exactly why the JSON was rejected.","triggerScenarios":"Passing `loadAgent` with `options.type === 'json'` and a `options.json` string that is not valid JSON: trailing commas, single quotes, unquoted keys, an unterminated string, or a value that is not an object. Also triggered when the inline string is empty or contains a markdown fence around the JSON.","commonSituations":"Hand-written JSON in a config file with a trailing comma; copy-pasting an AgentCard from docs that includes ` ```json ` fences; reading the JSON from a file but forgetting to strip a BOM or surrounding whitespace; a template literal that produced malformed output.","solutions":["Validate the JSON string with `JSON.parse` in isolation before passing it to loadAgent, and fix the syntax error reported.","Strip markdown code fences and surrounding whitespace/prose from the string.","Load the card from a URL (`options.type === 'url'`) instead of inline to let the resolver fetch a clean copy.","If the JSON is generated, run the generator's output through a JSON schema validator for AgentCard."],"exampleFix":"// before\nawait manager.loadAgent('rev', { type: 'json', json: `{ name: 'rev' }` }); // unquoted keys\n\n// after\nawait manager.loadAgent('rev', { type: 'json', json: JSON.stringify({ name: 'rev' }) });","handlingStrategy":"validation","validationCode":"function tryParseAgentCardJson(name: string, json: string): unknown {\n  try {\n    return JSON.parse(json);\n  } catch (e) {\n    throw new Error(\n      `Invalid inline agent card JSON for '${name}': ${(e as Error).message}`,\n    );\n  }\n}\n\nconst card = tryParseAgentCardJson('rev', options.json);\nawait manager.loadAgent('rev', { type: 'json', json: JSON.stringify(card) });","typeGuard":"function isParsableJson(s: string): boolean {\n  try { JSON.parse(s); return true; } catch { return false; }\n}","tryCatchPattern":"try {\n  await manager.loadAgent('rev', { type: 'json', json });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Failed to parse inline agent card JSON')) {\n    // fall back to loading from URL, or prompt user for corrected JSON\n  }\n  throw e;\n}","preventionTips":["Parse and validate inline JSON in a test before shipping the config.","Generate inline JSON with JSON.stringify rather than hand-writing it.","Prefer URL-based loading for cards that have a canonical home."],"tags":["a2a","agent-card","json","validation"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}