{"record":{"id":"5d47d27295589419","repo":"alibaba/nacos","slug":"duplicate-version-label-label","errorCode":null,"errorMessage":"Duplicate Version label: {label}","messagePattern":"Duplicate Version label: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java","lineNumber":480,"sourceCode":"                    && entry.getLabels().contains(label.getKey())) {\n                    presentInCatalog = true;\n                    break;\n                }\n            }\n            if (!presentInCatalog) {\n                throw new IllegalArgumentException(\n                    \"Online Version label is missing from versionCatalog: \" + label.getKey());\n            }\n        }\n    }\n    \n    private static void validateCatalogLabels(List<String> labels, Set<String> allLabels) {\n        requireNonNull(labels, \"versionCatalog.labels\");\n        Set<String> entryLabels = new HashSet<String>();\n        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    }","sourceCodeStart":462,"sourceCodeEnd":498,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java#L462-L498","documentation":"Thrown by validateCatalogLabels when a non-latest Version label appears more than once, either within a single catalog entry or across all entries (labels are globally unique across the whole catalog). The validator maintains a per-entry set and a shared all-labels set and rejects any label that fails to add to either. The \"latest\" label is excluded by validateNonLatestLabel.","triggerScenarios":"Two catalog entries both carrying the label \"stable\"; one entry listing \"stable\" twice. Because labels resolve to exactly one Version, they must be globally unique.","commonSituations":"Moving a label from one Version to another by adding it to the new entry without removing it from the old; importing labels per-Version without enforcing global uniqueness.","solutions":["Ensure each non-latest label key is used by at most one online catalog entry.","When moving a label, remove it from the previous entry before adding it to the new one.","Validate label uniqueness across the whole catalog before submission using a Set accumulator."],"exampleFix":"// before\nentryA.setLabels(List.of(\"stable\")); entryB.setLabels(List.of(\"stable\"));\n// after\nentryA.setLabels(List.of(\"stable\")); entryB.setLabels(List.of(\"canary\"));","handlingStrategy":"validation","validationCode":"static void checkCatalogLabelsUnique(List<AgentVersionCatalogEntry> entries) {\n    Set<String> all = new HashSet<>();\n    for (var entry : entries) {\n        Set<String> perEntry = new HashSet<>();\n        for (String label : entry.getLabels()) {\n            if (!perEntry.add(label) || !all.add(label)) {\n                throw new IllegalArgumentException(\"Duplicate Version label: \" + label);\n            }\n        }\n    }\n}","typeGuard":"static boolean catalogLabelsAreUnique(List<AgentVersionCatalogEntry> entries) {\n    Set<String> all = new HashSet<>();\n    for (var entry : entries) {\n        Set<String> perEntry = new HashSet<>();\n        for (String label : entry.getLabels()) {\n            if (!perEntry.add(label) || !all.add(label)) return false;\n        }\n    }\n    return true;\n}","tryCatchPattern":"try {\n    AgentModelValidator.validateAgent(agent);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Duplicate Version label\")) {\n        // remove the duplicated label from all but one entry\n    }\n}","preventionTips":["Enforce global label uniqueness across the whole catalog, not just per entry.","When moving a label, remove it from the previous entry first.","Accumulate labels into a shared Set during catalog construction."],"tags":["ai-agent","validation","labels","catalog","uniqueness","illegal-argument"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}