google-gemini/gemini-cli · error
Agent card is missing.
Error message
Agent card is missing.
What it means
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.
Source
Thrown at packages/core/src/agents/a2aUtils.ts:260
}
if ('uri' in fileData && fileData.uri) {
return `File: ${fileData.uri}`;
}
return `File: [binary/unnamed]`;
}
return '';
}
/**
* Normalizes proto field name aliases that the SDK doesn't handle yet.
* The A2A proto spec uses `supported_interfaces` and `protocol_binding`,
* while the SDK expects `additionalInterfaces` and `transport`.
* TODO: Remove once @a2a-js/sdk handles these aliases natively.
*/
export function normalizeAgentCard(card: unknown): AgentCard {
if (!isObject(card)) {
throw new Error('Agent card is missing.');
}
// Shallow-copy to avoid mutating the SDK's cached object.
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const result = { ...card } as unknown as AgentCard;
// Map supportedInterfaces → additionalInterfaces if needed
if (!result.additionalInterfaces) {
const raw = card;
if (Array.isArray(raw['supportedInterfaces'])) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
result.additionalInterfaces = raw[
'supportedInterfaces'
] as AgentInterface[];
}
}
// Map protocolBinding → transport on each interfaceView on GitHub (pinned to 5024443c72)
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).
Example fix
// before
await manager.loadAgent('svc', { type: 'json', json: rawJson });
// after
const parsed = JSON.parse(rawJson);
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
throw new Error('agent_card_json must decode to a single object');
}
await manager.loadAgent('svc', { type: 'json', json: rawJson }); Defensive patterns
Strategy: type-guard
Validate before calling
function isPlainObject(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
}
let card: unknown;
if (options.type === 'json') card = JSON.parse(options.json);
else card = await resolver.resolve(options.url, '');
if (!isPlainObject(card)) {
throw new Error('Agent card must decode to a non-null object.');
}
await manager.loadAgent(name, options); Type guard
function isAgentCardLike(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v)
&& typeof (v as { name?: unknown }).name === 'string';
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Failed to parse inline agent card JSON for agent '${name}':
- Agent with name '${name}' is already loaded.
- Agent '${agentName}' not found.
- Remote agent '${def.name}' has neither agentCardUrl nor agen
- Invalid taskId: ${taskId}
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/06299890b5b517ef.
Report an issue: GitHub.