{"record":{"id":"b813e40334feccd6","repo":"alibaba/nacos","slug":"name-must-be-a-json-object-b813e4","errorCode":null,"errorMessage":"${name} must be a JSON object","messagePattern":"(.+?) 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":367,"sourceCode":"\nfunction validateUniqueProtocols(callInterfaces: AgentCallInterface[]): AgentCallInterface[] {\n  const protocols = new Set<string>();\n  for (const callInterface of callInterfaces) {\n    if (protocols.has(callInterface.protocol)) {\n      throw new Error(`protocol must be unique: ${callInterface.protocol}`);\n    }\n    protocols.add(callInterface.protocol);\n  }\n  return callInterfaces;\n}\n\nfunction serializeOptionalObject(value: string, name: string): string | undefined {\n  if (!value.trim()) {\n    return undefined;\n  }\n  const parsed = parseJson(value, name);\n  if (parsed === null || Array.isArray(parsed) || typeof parsed !== 'object') {\n    throw new Error(`${name} must be a JSON object`);\n  }\n  return JSON.stringify(parsed);\n}\n\nfunction serializeCallInterfaces(\n  values: AgentEditorValues,\n  protocolEditors?: StructuredProtocolEditorValues[],\n): string {\n  const agentName = required(values.agentName, 'agentName');\n  const version = required(values.version, 'version');\n  if (protocolEditors) {\n    if (protocolEditors.length === 0) {\n      throw new Error('at least one protocol is required');\n    }\n    return JSON.stringify(validateUniqueProtocols(protocolEditors.map(\n      (editor) => buildStructuredCallInterface(agentName, version, editor),\n    )));\n  }","sourceCodeStart":349,"sourceCodeEnd":385,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/console-ui-next/src/pages/newAgent/agent-console-model.ts#L349-L385","documentation":"Thrown by serializeOptionalObject when a non-empty JSON value parses to something that is not a plain object — null, an array, or a primitive. The helper is used for optional object-typed fields that may be omitted (empty string = undefined) but, when present, must be an object.","triggerScenarios":"User enters an array or null or a number in an optional object field (e.g. capabilities, securitySchemes) instead of a key-value object.","commonSituations":"Field accepts a JSON object but user provides a JSON array. Placeholder defaults to 'null'. Misreading the field as a list.","solutions":["Provide a JSON object {\"key\":\"value\"} or leave the field empty to omit it.","Convert arrays to keyed objects if the schema requires an object.","Validate the parsed type before submit."],"exampleFix":"// before\n[\"read\",\"write\"]\n\n// after\n{\"scope1\":\"read\",\"scope2\":\"write\"}  // or leave empty to omit","handlingStrategy":"type-guard","validationCode":"function checkOptionalObject(text, name) {\n  if (!text.trim()) return undefined;\n  const parsed = JSON.parse(text);\n  if (parsed === null || Array.isArray(parsed) || typeof parsed !== 'object') throw new Error(`${name} must be an object`);\n  return parsed;\n}","typeGuard":"function isPlainObject(v: unknown): v is Record<string, unknown> {\n  return v !== null && !Array.isArray(v) && typeof v === 'object';\n}","tryCatchPattern":"try { serializeOptionalObject(text, name); } catch (e) {\n  if (/must be a JSON object/.test(e.message)) { toast.error(`${name} must be an object`); }\n}","preventionTips":["Leave field empty to omit","Provide key-value object only","Validate type before submit"],"tags":["validation","json","object","form"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}