{"record":{"id":"f7f18f56e68959b3","repo":"alibaba/nacos","slug":"duplicate-endpoint-source-source","errorCode":null,"errorMessage":"Duplicate Endpoint source: {source}","messagePattern":"Duplicate Endpoint source: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java","lineNumber":526,"sourceCode":"        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            }\n        }\n    }\n    \n    private static void validateEndpointSourceOrder(List<EndpointSource> sourceOrder) {\n        requireNonNull(sourceOrder, \"endpointSourceOrder\");\n        if (sourceOrder.isEmpty() || sourceOrder.size() > EndpointSource.values().length) {\n            throw new IllegalArgumentException(\"endpointSourceOrder must contain 1 or 2 sources\");\n        }\n        Set<EndpointSource> uniqueSources = new HashSet<EndpointSource>();\n        for (EndpointSource source : sourceOrder) {\n            requireNonNull(source, \"endpointSourceOrder item\");\n            if (!uniqueSources.add(source)) {\n                throw new IllegalArgumentException(\"Duplicate Endpoint source: \" + source);\n            }\n        }\n    }\n    \n    private static void validateDeclaredEndpoints(String namespaceId, String agentName,\n        String protocol, List<Endpoint> endpoints) {\n        if (endpoints == null) {\n            return;\n        }\n        if (endpoints.size() > MAX_DECLARED_ENDPOINTS) {\n            throw new IllegalArgumentException(\n                \"declaredEndpoints exceeds \" + MAX_DECLARED_ENDPOINTS + \" items\");\n        }\n        Set<EndpointNaturalKey> endpointKeys = new HashSet<EndpointNaturalKey>();\n        for (Endpoint endpoint : endpoints) {\n            validateEndpoint(endpoint);\n            EndpointNaturalKey key = EndpointNaturalKey.of(namespaceId, agentName, protocol,\n                endpoint);","sourceCodeStart":508,"sourceCodeEnd":544,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java#L508-L544","documentation":"Thrown by validateEndpointSourceOrder when the same EndpointSource value appears more than once in the list. Since endpointSourceOrder defines a strict preference sequence, repeating a source (e.g. [DECLARED, DECLARED]) is meaningless and is rejected. Each entry is also null-checked via requireNonNull before this uniqueness test.","triggerScenarios":"endpointSourceOrder = [DISCOVERED, DISCOVERED]; building the list by concatenating a default with an override that repeats the default.","commonSituations":"Defaulting the list to [DECLARED] then appending DECLARED again from config; copy-paste between interfaces that left a duplicate.","solutions":["List each EndpointSource at most once in endpointSourceOrder.","Deduplicate the list while preserving the intended first-preference order.","Construct the list explicitly from distinct EndpointSource values."],"exampleFix":"// before\ncallInterface.setEndpointSourceOrder(List.of(EndpointSource.DECLARED, EndpointSource.DECLARED));\n// after\ncallInterface.setEndpointSourceOrder(List.of(EndpointSource.DECLARED));","handlingStrategy":"validation","validationCode":"static List<EndpointSource> dedupSourceOrder(List<EndpointSource> order) {\n    return new ArrayList<>(new LinkedHashSet<>(order));\n}","typeGuard":"static boolean sourceOrderIsUnique(List<EndpointSource> order) {\n    return order == null || new HashSet<>(order).size() == order.size();\n}","tryCatchPattern":"try {\n    AgentModelValidator.validateCallInterface(ci);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Duplicate Endpoint source\")) {\n        ci.setEndpointSourceOrder(new ArrayList<>(new LinkedHashSet<>(ci.getEndpointSourceOrder())));\n    }\n}","preventionTips":["Never repeat an EndpointSource in the order list.","Construct the list from distinct values explicitly.","Deduplicate while preserving the intended first-preference order."],"tags":["ai-agent","validation","endpoint","uniqueness","illegal-argument"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}