{"record":{"id":"746984f9f5e418e4","repo":"alibaba/nacos","slug":"online-agent-version-protocols-must-contain-1-to-1","errorCode":null,"errorMessage":"Online Agent Version protocols must contain 1 to 16 values","messagePattern":"Online Agent Version protocols must contain 1 to 16 values","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/service/agent/metadata/AgentVersionCatalogBuilder.java","lineNumber":115,"sourceCode":"            List<String> versionProtocols = protocolsByVersion.get(version);\n            entry.setProtocols(Collections.unmodifiableList(versionProtocols));\n            entries.add(entry);\n        }\n        catalog.setOnlineVersions(Collections.unmodifiableList(entries));\n        AgentModelValidator.validateVersionCatalog(catalog);\n        return new Result(catalog, normalizedLabels);\n    }\n    \n    private static Map<String, List<String>> validateAndCopyProtocols(\n        Map<String, List<String>> onlineVersionProtocols) {\n        Map<String, List<String>> result = new LinkedHashMap<String, List<String>>();\n        for (Map.Entry<String, List<String>> entry : onlineVersionProtocols.entrySet()) {\n            String version = entry.getKey();\n            AgentValidationUtils.validateVersion(version);\n            List<String> protocols = entry.getValue();\n            if (protocols == null || protocols.isEmpty()\n                || protocols.size() > MAX_PROTOCOLS_PER_VERSION) {\n                throw new IllegalArgumentException(\n                    \"Online Agent Version protocols must contain 1 to \"\n                        + MAX_PROTOCOLS_PER_VERSION + \" values\");\n            }\n            Set<String> uniqueProtocols = new HashSet<String>();\n            List<String> protocolCopy = new ArrayList<String>(protocols.size());\n            for (String protocol : protocols) {\n                AgentValidationUtils.validateProtocol(protocol);\n                if (!uniqueProtocols.add(protocol)) {\n                    throw new IllegalArgumentException(\n                        \"Duplicate protocol for Agent Version \" + version + \": \" + protocol);\n                }\n                protocolCopy.add(protocol);\n            }\n            result.put(version, protocolCopy);\n        }\n        return result;\n    }\n    ","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/service/agent/metadata/AgentVersionCatalogBuilder.java#L97-L133","documentation":"Each online Agent Version must declare between 1 and 16 (MAX_PROTOCOLS_PER_VERSION) CallInterface protocols. The AgentVersionCatalogBuilder.validateAndCopyProtocols method (line 113) throws this when the protocols list for a version is null, empty, or exceeds 16 entries. This is a server-side validation during catalog derivation from Naming instance facts.","triggerScenarios":"Calling AgentVersionCatalogBuilder.build() with an onlineVersionProtocols map where a version key maps to null, an empty list, or a list with more than 16 protocol strings. This happens internally when the server reconstructs the catalog from registered Naming instances.","commonSituations":"An Agent Version registration that omitted all protocols; a client bug that registered zero protocols; an unusually broad Agent that supports more than 16 distinct protocols (unlikely but possible in large integrations).","solutions":["Ensure every online version has at least 1 and at most 16 protocols in its registration.","If a version legitimately needs more than 16 protocols, split it into multiple version entries or discuss raising MAX_PROTOCOLS_PER_VERSION with maintainers.","Audit the client registration code to verify the protocols list is always populated before submission."],"exampleFix":"// before\nMap<String,List<String>> protocols = Map.of(\"1.0.0\", Collections.emptyList());\nAgentVersionCatalogBuilder.build(protocols, labels);\n// after\nMap<String,List<String>> protocols = Map.of(\"1.0.0\", List.of(\"a2a\",\"mcp\"));\nAgentVersionCatalogBuilder.build(protocols, labels);","handlingStrategy":"validation","validationCode":"for (Map.Entry<String,List<String>> entry : onlineVersionProtocols.entrySet()) {\n    List<String> protocols = entry.getValue();\n    if (protocols == null || protocols.isEmpty() || protocols.size() > 16) {\n        throw new IllegalArgumentException(\"Version \" + entry.getKey()\n            + \" needs 1-16 protocols\");\n    }\n}","typeGuard":"public static boolean hasValidProtocolCount(Map<String,List<String>> map) {\n    for (List<String> protocols : map.values()) {\n        if (protocols == null || protocols.isEmpty() || protocols.size() > 16) return false;\n    }\n    return true;\n}","tryCatchPattern":"try {\n    AgentVersionCatalogBuilder.build(onlineVersionProtocols, labels);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"1 to 16 values\")) {\n        // fix the protocol list for the offending version\n    }\n    throw e;\n}","preventionTips":["Always populate at least one protocol per version before calling build().","Cap protocol list sizes at 16 in the client registration form.","Validate protocol counts in unit tests for each version registration."],"tags":["validation","ai-agent","version-catalog","protocols"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}