{"record":{"id":"51d82e00ffb36694","repo":"alibaba/nacos","slug":"agentcard-must-be-a-json-object-51d82e","errorCode":null,"errorMessage":"agentCard must be a JSON object","messagePattern":"agentCard must be a JSON object","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"console-ui-next/src/pages/newAgent/agent-console-model.ts","lineNumber":234,"sourceCode":"    'AgentCard interface protocolVersion',\n  );\n  return {\n    ...value,\n    url,\n    transport: protocolBinding,\n    protocolBinding,\n    protocolVersion,\n  };\n}\n\nfunction normalizeA2aAgentCard(\n  agentName: string,\n  version: string,\n  text: string,\n): { card: Record<string, unknown>; declaredEndpoints: AgentCallInterface['declaredEndpoints'] } {\n  const parsed = parseAgentCardJson(required(text, 'agentCard'));\n  if (!isObject(parsed)) {\n    throw new Error('agentCard must be a JSON object');\n  }\n  const card: Record<string, unknown> = { ...parsed, name: agentName, version };\n  const topProtocolVersion = optionalString(card.protocolVersion);\n  const preferredTransport = optionalString(card.preferredTransport);\n  let interfaces: Record<string, unknown>[];\n  if (Array.isArray(card.supportedInterfaces) && card.supportedInterfaces.length > 0) {\n    interfaces = card.supportedInterfaces.map((item) => normalizeA2aInterface(\n      item,\n      preferredTransport,\n      topProtocolVersion,\n    ));\n  } else {\n    const preferred = normalizeA2aInterface({\n      url: card.url,\n      protocolBinding: preferredTransport,\n      protocolVersion: topProtocolVersion,\n    });\n    interfaces = [preferred];","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/console-ui-next/src/pages/newAgent/agent-console-model.ts#L216-L252","documentation":"Thrown by normalizeA2aAgentCard after parsing the agentCard JSON text: the parsed value is not a plain object (it is an array, primitive, or null). The AgentCard must be a top-level JSON object so its fields (name, version, supportedInterfaces) can be read.","triggerScenarios":"User enters a JSON array '[...]' or a bare string/number as the agentCard, or 'null'. parseAgentCardJson succeeds but the result is non-object.","commonSituations":"User wraps the card in an array by mistake. User pastes only the supportedInterfaces array thinking it is the whole card.","solutions":["Provide a full AgentCard object with top-level fields, not an array.","Wrap a bare array in an object: {\"supportedInterfaces\":[...],\"name\":\"...\",\"version\":\"...\"}.","Validate the root type is an object before submit."],"exampleFix":"// before\n[{\"url\":\"https://a.example.com\",\"transport\":\"GRPC\"}]\n\n// after\n{\"name\":\"my-agent\",\"version\":\"1.0.0\",\"supportedInterfaces\":[{\"url\":\"https://a.example.com\",\"transport\":\"GRPC\"}]}","handlingStrategy":"type-guard","validationCode":"function checkAgentCard(parsed) { if (parsed === null || Array.isArray(parsed) || typeof parsed !== 'object') throw new Error('agentCard must be an object'); }","typeGuard":"function isAgentCardObject(v: unknown): v is Record<string, unknown> {\n  return v !== null && !Array.isArray(v) && typeof v === 'object';\n}","tryCatchPattern":"try { normalizeA2aAgentCard(name, ver, text); } catch (e) {\n  if (/agentCard must be a JSON object/.test(e.message)) { toast.error('Wrap the card in a JSON object'); }\n}","preventionTips":["Wrap card fields in a top-level object","Validate root type before submit","Use the structured editor for AgentCard"],"tags":["validation","agentcard","json","a2a"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}