alibaba/nacos · error · IllegalArgumentException
Duplicate CallInterface protocol: {callInterface.protocol}
Error message
Duplicate CallInterface protocol: {callInterface.protocol} What it means
Thrown by validateCallInterfaces when two CallInterface entries in the same Version share the same protocol. Each protocol must map to exactly one CallInterface within a Version, so the call target is unambiguous. The validator accumulates protocols in a Set and rejects the second occurrence.
Source
Thrown at api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java:511
AgentValidationUtils.validateProtocol(protocol);
if (!uniqueProtocols.add(protocol)) {
throw new IllegalArgumentException("Duplicate protocol: " + protocol);
}
}
}
private static void validateCallInterfaces(String namespaceId, String agentName,
List<AgentCallInterface> callInterfaces) {
requireNonNull(callInterfaces, "callInterfaces");
if (callInterfaces.isEmpty() || callInterfaces.size() > MAX_CALL_INTERFACES) {
throw new IllegalArgumentException(
"callInterfaces must contain 1 to " + MAX_CALL_INTERFACES + " items");
}
Set<String> protocols = new HashSet<String>();
for (AgentCallInterface callInterface : callInterfaces) {
validateCallInterface(namespaceId, agentName, callInterface);
if (!protocols.add(callInterface.getProtocol())) {
throw new IllegalArgumentException(
"Duplicate CallInterface protocol: " + callInterface.getProtocol());
}
}
}
private static void validateEndpointSourceOrder(List<EndpointSource> sourceOrder) {
requireNonNull(sourceOrder, "endpointSourceOrder");
if (sourceOrder.isEmpty() || sourceOrder.size() > EndpointSource.values().length) {
throw new IllegalArgumentException("endpointSourceOrder must contain 1 or 2 sources");
}
Set<EndpointSource> uniqueSources = new HashSet<EndpointSource>();
for (EndpointSource source : sourceOrder) {
requireNonNull(source, "endpointSourceOrder item");
if (!uniqueSources.add(source)) {
throw new IllegalArgumentException("Duplicate Endpoint source: " + source);
}
}
}View on GitHub (pinned to 9b989acdf1)
Solutions
- Give each CallInterface in a Version a distinct protocol value.
- If two interfaces share a protocol, merge them into one CallInterface with combined declared endpoints / endpoint source order.
- Deduplicate by protocol before submission.
Example fix
// before
ci1.setProtocol("mcp"); ci2.setProtocol("mcp"); detail.setCallInterfaces(List.of(ci1, ci2));
// after
ci1.setProtocol("mcp"); ci2.setProtocol("a2a"); detail.setCallInterfaces(List.of(ci1, ci2)); Defensive patterns
Strategy: validation
Validate before calling
static void checkCallInterfaceProtocolsUnique(List<AgentCallInterface> cis) {
Set<String> seen = new HashSet<>();
for (var ci : cis) {
if (!seen.add(ci.getProtocol())) {
throw new IllegalArgumentException(
"Duplicate CallInterface protocol: " + ci.getProtocol());
}
}
} Type guard
static boolean callInterfaceProtocolsUnique(List<AgentCallInterface> cis) {
long unique = cis.stream().map(AgentCallInterface::getProtocol).distinct().count();
return unique == cis.size();
} Try / catch
try {
AgentModelValidator.validateVersionDetail(detail);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Duplicate CallInterface protocol")) {
// merge interfaces sharing a protocol, or assign distinct protocols
}
} Prevention
- Give each CallInterface in a Version a distinct protocol.
- Merge interfaces that differ only by endpoints into one.
- Deduplicate by protocol before submission.
When it happens
Trigger: A Version with two CallInterface entries both having protocol = "mcp" (e.g. one for declared endpoints and one duplicated by mistake). Copy-pasting a CallInterface and changing only its endpoints but not its protocol.
Common situations: Cloning a CallInterface to add a second endpoint set without giving it a distinct protocol; merging interface lists from two sources that both define an MCP interface.
Related errors
- Duplicate tag: {tag}
- Duplicate Version label: {label}
- Duplicate protocol: {protocol}
- callInterfaces must contain 1 to {MAX_CALL_INTERFACES} items
- endpointSourceOrder must contain 1 or 2 sources
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/116a90c6c50626c2.
Report an issue: GitHub.