{"record":{"id":"465ccbfb5781f931","repo":"alibaba/nacos","slug":"duplicate-online-agent-version-version-value","errorCode":null,"errorMessage":"Duplicate online Agent Version: {version.value}","messagePattern":"Duplicate online Agent Version: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java","lineNumber":259,"sourceCode":"        List<AgentVersionCatalogEntry> versions = catalog.getOnlineVersions();\n        requireNonNull(versions, \"versionCatalog.onlineVersions\");\n        if (versions.isEmpty()) {\n            if (catalog.getLatestVersion() != null) {\n                throw new IllegalArgumentException(\n                    \"latestVersion must be absent when onlineVersions is empty\");\n            }\n            return;\n        }\n        \n        AgentValidationUtils.validateVersion(catalog.getLatestVersion());\n        Set<String> versionValues = new HashSet<String>();\n        Set<String> labelValues = new HashSet<String>();\n        boolean latestFound = false;\n        for (AgentVersionCatalogEntry entry : versions) {\n            requireNonNull(entry, \"versionCatalog entry\");\n            AgentVersion version = AgentVersion.parse(entry.getVersion());\n            if (!versionValues.add(version.getValue())) {\n                throw new IllegalArgumentException(\n                    \"Duplicate online Agent Version: \" + version.getValue());\n            }\n            latestFound |= catalog.getLatestVersion().equals(version.getValue());\n            validateCatalogLabels(entry.getLabels(), labelValues);\n            validateProtocols(entry.getProtocols(), \"versionCatalog.protocols\");\n        }\n        if (!latestFound) {\n            throw new IllegalArgumentException(\n                \"latestVersion must identify an onlineVersions entry\");\n        }\n    }\n    \n    /**\n     * Validate a raw runtime Endpoint management snapshot.\n     *\n     * @param snapshot runtime Endpoint snapshot\n     * @throws IllegalArgumentException when the snapshot is invalid\n     */","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java#L241-L277","documentation":"Thrown by validateVersionCatalog as an IllegalArgumentException when two entries in onlineVersions resolve to the same version value. The catalog requires unique versions; duplicates would make routing and 'latest' resolution ambiguous.","triggerScenarios":"Passing a catalog whose onlineVersions contains two AgentVersionCatalogEntry items whose parsed AgentVersion.getValue() are equal (e.g. both \"1.2.0\").","commonSituations":"A version was added twice due to a retry/race; two entries used different strings (\"1.2\" and \"1.2.0\") that normalize to the same value; a migration script merged catalogs and created overlaps.","solutions":["Deduplicate onlineVersions by version value before validation.","When adding a version, check for an existing equal value first and update instead of inserting.","If different spellings normalize to the same value, canonicalize all version strings."],"exampleFix":"// before\nList<AgentVersionCatalogEntry> versions = List.of(\n    entry(\"1.2.0\"), entry(\"1.2.0\"));\ncatalog.setOnlineVersions(versions);\nAgentModelValidator.validateVersionCatalog(catalog); // throws\n\n// after\nList<AgentVersionCatalogEntry> versions = versions.stream()\n    .collect(Collectors.toMap(\n        e -> AgentVersion.parse(e.getVersion()).getValue(),\n        Function.identity(), (a, b) -> a))\n    .values().stream().toList();\ncatalog.setOnlineVersions(versions);\nAgentModelValidator.validateVersionCatalog(catalog); // ok","handlingStrategy":"validation","validationCode":"Set<String> seen = new HashSet<>();\nList<AgentVersionCatalogEntry> dedup = new ArrayList<>();\nfor (AgentVersionCatalogEntry e : catalog.getOnlineVersions()) {\n    if (seen.add(AgentVersion.parse(e.getVersion()).getValue())) dedup.add(e);\n}\ncatalog.setOnlineVersions(dedup);\nAgentModelValidator.validateVersionCatalog(catalog);","typeGuard":"static boolean versionsAreUnique(List<AgentVersionCatalogEntry> entries) {\n    Set<String> vals = new HashSet<>();\n    for (AgentVersionCatalogEntry e : entries) {\n        if (!vals.add(AgentVersion.parse(e.getVersion()).getValue())) return false;\n    }\n    return true;\n}","tryCatchPattern":null,"preventionTips":["Canonicalize version strings (use AgentVersion.parse(...).getValue()) before comparing.","Enforce uniqueness at insert time in the catalog builder.","When merging catalogs from multiple sources, dedupe by version value."],"tags":["java","nacos","ai","agents","validation","catalog","duplicate"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}