{"record":{"id":"b07034fb285692d2","repo":"alibaba/nacos","slug":"duplicate-protocol-protocol","errorCode":null,"errorMessage":"Duplicate protocol: {protocol}","messagePattern":"Duplicate protocol: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java","lineNumber":495,"sourceCode":"        for (String label : labels) {\n            AgentValidationUtils.validateNonLatestLabel(label);\n            if (!entryLabels.add(label) || !allLabels.add(label)) {\n                throw new IllegalArgumentException(\"Duplicate Version label: \" + label);\n            }\n        }\n    }\n    \n    private static void validateProtocols(List<String> protocols, String fieldName) {\n        requireNonNull(protocols, fieldName);\n        if (protocols.isEmpty() || protocols.size() > MAX_CALL_INTERFACES) {\n            throw new IllegalArgumentException(\n                fieldName + \" must contain 1 to \" + MAX_CALL_INTERFACES + \" values\");\n        }\n        Set<String> uniqueProtocols = new HashSet<String>();\n        for (String protocol : protocols) {\n            AgentValidationUtils.validateProtocol(protocol);\n            if (!uniqueProtocols.add(protocol)) {\n                throw new IllegalArgumentException(\"Duplicate protocol: \" + protocol);\n            }\n        }\n    }\n    \n    private static void validateCallInterfaces(String namespaceId, String agentName,\n        List<AgentCallInterface> callInterfaces) {\n        requireNonNull(callInterfaces, \"callInterfaces\");\n        if (callInterfaces.isEmpty() || callInterfaces.size() > MAX_CALL_INTERFACES) {\n            throw new IllegalArgumentException(\n                \"callInterfaces must contain 1 to \" + MAX_CALL_INTERFACES + \" items\");\n        }\n        Set<String> protocols = new HashSet<String>();\n        for (AgentCallInterface callInterface : callInterfaces) {\n            validateCallInterface(namespaceId, agentName, callInterface);\n            if (!protocols.add(callInterface.getProtocol())) {\n                throw new IllegalArgumentException(\n                    \"Duplicate CallInterface protocol: \" + callInterface.getProtocol());\n            }","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java#L477-L513","documentation":"Thrown by validateProtocols when the same protocol string appears more than once in a protocols list. Protocols within one list must be unique; duplicates would create ambiguous call-interface resolution. This runs after per-protocol format validation (AgentValidationUtils.validateProtocol) and the size check.","triggerScenarios":"A catalog entry protocols list containing [\"mcp\", \"a2a\", \"mcp\"]. Concatenating default and override protocol lists without dedup.","commonSituations":"Merging a base protocol set with per-environment additions that re-include a base protocol; case mismatch is NOT caught here (exact match), so \"MCP\" and \"mcp\" would both pass but collide downstream.","solutions":["Deduplicate the protocols list before submission using a LinkedHashSet.","Normalize protocol strings to the canonical lowercase form before dedup.","Audit code that composes protocol lists from multiple sources."],"exampleFix":"// before\nentry.setProtocols(List.of(\"mcp\", \"a2a\", \"mcp\"));\n// after\nentry.setProtocols(new ArrayList<>(new LinkedHashSet<>(List.of(\"mcp\", \"a2a\", \"mcp\"))));","handlingStrategy":"validation","validationCode":"static List<String> dedupProtocols(List<String> protocols) {\n    return new ArrayList<>(new LinkedHashSet<>(protocols));\n}","typeGuard":"static boolean protocolsAreUnique(List<String> protocols) {\n    return protocols == null || new HashSet<>(protocols).size() == protocols.size();\n}","tryCatchPattern":"try {\n    AgentModelValidator.validateAgent(agent);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Duplicate protocol\")) {\n        // dedup the offending protocols list\n    }\n}","preventionTips":["Deduplicate protocol lists with a LinkedHashSet before submission.","Normalize protocol strings to canonical lowercase before dedup.","Audit code that composes protocol lists from multiple sources."],"tags":["ai-agent","validation","protocols","uniqueness","illegal-argument"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}