google-gemini/gemini-cli · critical · AgentLoadError
Unexpected state: neither agent_card_json nor agent_card_url
Error message
Unexpected state: neither agent_card_json nor agent_card_url present on remote agent
What it means
markdownToAgentDefinition builds a RemoteAgentDefinition only after the frontmatter passed schema validation, so a remote agent is expected to carry either agent_card_json or agent_card_url. Reaching this throw means the schema accepted a remote-kind object without either field - an invariant violation indicating a gap between markdownFrontmatterSchema and this builder. The 'Unexpected state' wording marks it as a shouldn't-happen condition.
Source
Thrown at packages/core/src/agents/agentLoader.ts:540
? convertFrontmatterAuthToConfig(markdown.auth)
: undefined,
inputConfig,
metadata,
};
if (
'agent_card_json' in markdown &&
markdown.agent_card_json !== undefined
) {
base.agentCardJson = markdown.agent_card_json;
return base;
}
if ('agent_card_url' in markdown && markdown.agent_card_url !== undefined) {
base.agentCardUrl = markdown.agent_card_url;
return base;
}
throw new AgentLoadError(
metadata?.filePath || 'unknown',
'Unexpected state: neither agent_card_json nor agent_card_url present on remote agent',
);
}
// If a model is specified, use it. Otherwise, inherit
const modelName = markdown.model || 'inherit';
const mcpServers: Record<string, MCPServerConfig> = {};
if (markdown.mcp_servers) {
for (const [name, config] of Object.entries(markdown.mcp_servers)) {
let authProviderType: AuthProviderType | undefined = undefined;
let oauth: MCPOAuthConfig | undefined = undefined;
if (config.auth) {
if (config.auth.type === 'google-credentials') {
authProviderType = AuthProviderType.GOOGLE_CREDENTIALS;
oauth = {View on GitHub (pinned to 5024443c72)
Solutions
- If authoring a file, add either agent_card_url or agent_card_json to the remote frontmatter.
- If this fires from a valid file, the schema is too permissive - tighten markdownFrontmatterSchema's remote branch to require one card field.
- If constructing the object in code, run it through parseAgentMarkdown/validate first.
- Report as a loader bug since the schema should have caught it earlier.
Example fix
# before --- name: remote-svc kind: remote # no card field --- # after --- name: remote-svc kind: remote agent_card_url: https://svc.example/.well-known/agent-card.json ---
Defensive patterns
Strategy: validation
Validate before calling
function hasRemoteCardField(md: { kind?: string }): boolean {
return 'agent_card_json' in md || 'agent_card_url' in md;
}
if (frontmatter.kind === 'remote' && !hasRemoteCardField(frontmatter)) {
throw new Error('Remote agent requires agent_card_json or agent_card_url.');
} Prevention
- Always include agent_card_url (or agent_card_json) on remote agents.
- If this fires despite a valid file, tighten the schema's remote branch.
- Construct remote definitions only through parseAgentMarkdown.
When it happens
Trigger: The schema union matched a remote branch that does not enforce agent_card_json/agent_card_url as required; a discriminator matched 'remote' via a different key; an extension to the schema added a remote variant without the card fields; the frontmatter was constructed programmatically and bypassed strict parsing.
Common situations: A schema refactor loosened the remote branch; a test constructed a FrontmatterAgentDefinition object directly without running the schema; a feature added a new remote kind without updating the builder's guard.
Related errors
- Validation failed: ${formatZodError(result.error, 'Remote Ag
- Could not read file: ${getErrorMessage(error)}
- Invalid agent definition: Missing mandatory YAML frontmatter
- YAML frontmatter parsing failed: ${getErrorMessage(error)}
- Validation failed: ${formatZodError(result.error, 'Agent Def
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/2bb34cb0c2c7d29b.
Report an issue: GitHub.