{"record":{"id":"dbe68437134a66b7","repo":"alibaba/nacos","slug":"duplicate-callinterface-protocol-callinterface-g","errorCode":null,"errorMessage":"Duplicate CallInterface protocol: {callInterface.getProtocol()}","messagePattern":"Duplicate CallInterface protocol: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/service/agent/storage/AgentVersionContentSerializer.java","lineNumber":166,"sourceCode":"                + AgentVersionContent.KIND);\n        }\n        if (!Integer.valueOf(AgentVersionContent.SCHEMA_VERSION)\n            .equals(content.getSchemaVersion())) {\n            throw new IllegalArgumentException(\"AgentVersionContent schemaVersion must be \"\n                + AgentVersionContent.SCHEMA_VERSION);\n        }\n        List<AgentCallInterface> callInterfaces = content.getCallInterfaces();\n        if (callInterfaces == null || callInterfaces.isEmpty()\n            || callInterfaces.size() > MAX_CALL_INTERFACES) {\n            throw new IllegalArgumentException(\n                \"AgentVersionContent callInterfaces must contain 1 to \" + MAX_CALL_INTERFACES\n                    + \" items\");\n        }\n        Set<String> protocols = new HashSet<String>();\n        for (AgentCallInterface callInterface : callInterfaces) {\n            AgentModelValidator.validateCallInterface(callInterface);\n            if (!protocols.add(callInterface.getProtocol())) {\n                throw new IllegalArgumentException(\n                    \"Duplicate CallInterface protocol: \" + callInterface.getProtocol());\n            }\n        }\n    }\n    \n    private static Map<String, Object> toStorageProjection(AgentVersionContent content) {\n        Map<String, Object> result = new LinkedHashMap<String, Object>();\n        result.put(\"kind\", AgentVersionContent.KIND);\n        result.put(\"schemaVersion\", AgentVersionContent.SCHEMA_VERSION);\n        List<Map<String, Object>> callInterfaces = new ArrayList<Map<String, Object>>();\n        for (AgentCallInterface callInterface : content.getCallInterfaces()) {\n            callInterfaces.add(toStorageProjection(callInterface));\n        }\n        result.put(\"callInterfaces\", callInterfaces);\n        return result;\n    }\n    \n    private static Map<String, Object> toStorageProjection(AgentCallInterface callInterface) {","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/service/agent/storage/AgentVersionContentSerializer.java#L148-L184","documentation":"Thrown by validate when two callInterfaces in the same AgentVersionContent share the same protocol value. Protocols must be unique within a version because each protocol maps to exactly one call interface binding.","triggerScenarios":"Serializing/deserializing content where two AgentCallInterface entries have identical getProtocol(). The HashSet.add returns false on the duplicate, triggering the error with the offending protocol name.","commonSituations":"A publisher registers two interfaces for the same protocol (e.g. two 'a2a' or two 'mcp' entries) by mistake, or a copy-paste error when building the list.","solutions":["Dedupe callInterfaces by protocol before serializing — keep one entry per protocol.","If you need multiple bindings for one protocol, merge them into a single AgentCallInterface or reconsider the model."],"exampleFix":"// before\nList<AgentCallInterface> ifaces = List.of(a2aV1, a2aV2); // both protocol=\"a2a\"\n\n// after\nList<AgentCallInterface> ifaces = List.of(a2aV1); // one per protocol","handlingStrategy":"validation","validationCode":"Set<String> seen = new HashSet<>();\nfor (AgentCallInterface ci : callInterfaces) {\n    if (!seen.add(ci.getProtocol())) {\n        throw new IllegalArgumentException(\"duplicate protocol: \" + ci.getProtocol());\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Dedupe callInterfaces by protocol before serializing.","Keep one binding per protocol per version."],"tags":["validation","agent-version","duplicate","call-interfaces","illegal-argument"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}