alibaba/nacos · error · Error

AgentCard interface must be a JSON object

Error message

AgentCard interface must be a JSON object

What it means

Thrown by normalizeA2aInterface when an element of the AgentCard's supportedInterfaces array is not a plain object. The function expects each interface entry to be a JSON object with fields like url, protocolBinding, transport. Primitives, arrays, or null are rejected before any field extraction.

Source

Thrown at console-ui-next/src/pages/newAgent/agent-console-model.ts:201

  switch (key) {
    case 'RUNTIME,DECLARED':
      return 'runtime-declared';
    case 'DECLARED':
      return 'declared-only';
    case 'RUNTIME':
      return 'runtime-only';
    default:
      return 'declared-runtime';
  }
}

function normalizeA2aInterface(
  value: unknown,
  fallbackTransport?: string,
  fallbackVersion?: string,
): Record<string, unknown> {
  if (!isObject(value)) {
    throw new Error('AgentCard interface must be a JSON object');
  }
  const url = required(optionalString(value.url) || '', 'AgentCard interface url');
  endpointKey(url, optionalString(value.protocolBinding)
    || optionalString(value.transport)
    || fallbackTransport
    || '');
  const protocolBinding = validateTransport(
    optionalString(value.protocolBinding)
      || optionalString(value.transport)
      || fallbackTransport
      || '',
  );
  const protocolVersion = required(
    optionalString(value.protocolVersion) || fallbackVersion || '',
    'AgentCard interface protocolVersion',
  );
  return {
    ...value,

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Ensure every element of supportedInterfaces is an object, e.g. {"url":"https://...","transport":"GRPC"}.
  2. Validate the AgentCard against the A2A AgentCard JSON schema before submission.
  3. If a single string transport was intended, wrap it: replace "grpc" with {"transport":"GRPC","url":"https://..."}.

Example fix

// before
{"supportedInterfaces":["GRPC","HTTP"]}

// after
{"supportedInterfaces":[{"url":"https://a.example.com","transport":"GRPC"}]}
Defensive patterns

Strategy: type-guard

Validate before calling

function checkInterfaces(arr) { arr.forEach((it) => { if (it === null || Array.isArray(it) || typeof it !== 'object') throw new Error('Each interface must be an object'); }); }

Type guard

function isInterfaceObject(v: unknown): v is Record<string, unknown> {
  return v !== null && !Array.isArray(v) && typeof v === 'object';
}

Try / catch

try { normalizeA2aAgentCard(name, ver, text); } catch (e) {
  if (/AgentCard interface must be a JSON object/.test(e.message)) { toast.error('supportedInterfaces entries must be objects'); }
}

Prevention

When it happens

Trigger: The AgentCard's supportedInterfaces contains a string, number, null, or an array instead of an interface object, e.g. [{"url":"..."}, "grpc"] or supportedInterfaces: "http".

Common situations: Manually authoring an AgentCard JSON and putting a transport name directly in the array instead of an object. Schema mismatch between the editor and the A2A spec.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/9ff64030f5a23f5c. Report an issue: GitHub.