{"record":{"id":"06299890b5b517ef","repo":"google-gemini/gemini-cli","slug":"agent-card-is-missing","errorCode":null,"errorMessage":"Agent card is missing.","messagePattern":"Agent card is missing\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/agents/a2aUtils.ts","lineNumber":260,"sourceCode":"    }\n    if ('uri' in fileData && fileData.uri) {\n      return `File: ${fileData.uri}`;\n    }\n    return `File: [binary/unnamed]`;\n  }\n\n  return '';\n}\n\n/**\n * Normalizes proto field name aliases that the SDK doesn't handle yet.\n * The A2A proto spec uses `supported_interfaces` and `protocol_binding`,\n * while the SDK expects `additionalInterfaces` and `transport`.\n * TODO: Remove once @a2a-js/sdk handles these aliases natively.\n */\nexport function normalizeAgentCard(card: unknown): AgentCard {\n  if (!isObject(card)) {\n    throw new Error('Agent card is missing.');\n  }\n\n  // Shallow-copy to avoid mutating the SDK's cached object.\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion\n  const result = { ...card } as unknown as AgentCard;\n\n  // Map supportedInterfaces → additionalInterfaces if needed\n  if (!result.additionalInterfaces) {\n    const raw = card;\n    if (Array.isArray(raw['supportedInterfaces'])) {\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion\n      result.additionalInterfaces = raw[\n        'supportedInterfaces'\n      ] as AgentInterface[];\n    }\n  }\n\n  // Map protocolBinding → transport on each interface","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/core/src/agents/a2aUtils.ts#L242-L278","documentation":"normalizeAgentCard rejects its input when isObject(card) is false, meaning the value passed in is null, undefined, a primitive, or an array. The function is called in A2AClientManager.loadAgent after either JSON.parse(options.json) or DefaultAgentCardResolver.resolve(url). An empty/null card means the agent-card source produced nothing usable, so normalization cannot proceed.","triggerScenarios":"An inline agent_card_json that parses to null (e.g. the string 'null'); a remote card endpoint returning an empty 200 body that the resolver decoded to undefined; a malformed JSON literal that JSON.parse turned into a number/string; the resolver returned null because the endpoint served HTML or a redirect page.","commonSituations":"Wrong agent_card_url pointing at an HTML error page or login wall; agent_card_json set to an empty object string but actually null; a proxy rewriting the response to a placeholder; the A2A server not yet started so the endpoint returns a gateway page.","solutions":["If using type 'json', validate the parsed value is a non-null object before loading.","If using type 'url', curl the agent_card_url and confirm it returns JSON with an 'name'/'version' object.","Check for corporate proxies or auth walls replacing the card with HTML.","Ensure the remote A2A server is running and serving /.well-known/agent-card.json (or its configured path)."],"exampleFix":"// before\nawait manager.loadAgent('svc', { type: 'json', json: rawJson });\n\n// after\nconst parsed = JSON.parse(rawJson);\nif (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n  throw new Error('agent_card_json must decode to a single object');\n}\nawait manager.loadAgent('svc', { type: 'json', json: rawJson });","handlingStrategy":"type-guard","validationCode":"function isPlainObject(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nlet card: unknown;\nif (options.type === 'json') card = JSON.parse(options.json);\nelse card = await resolver.resolve(options.url, '');\nif (!isPlainObject(card)) {\n  throw new Error('Agent card must decode to a non-null object.');\n}\nawait manager.loadAgent(name, options);","typeGuard":"function isAgentCardLike(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v)\n    && typeof (v as { name?: unknown }).name === 'string';\n}","tryCatchPattern":null,"preventionTips":["Validate the parsed card shape before calling loadAgent.","curl the agent_card_url to confirm it serves JSON, not HTML.","Treat a null JSON literal as invalid at the config layer."],"tags":["a2a","agent-card","validation","precondition"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}