alibaba/nacos · error · Error

protocol must be unique: ${callInterface.protocol}

Error message

protocol must be unique: ${callInterface.protocol}

What it means

Thrown by validateUniqueProtocols when two callInterfaces share the same `protocol` value. Each protocol type (e.g. 'A2A', 'GRPC') may appear only once per agent; a duplicate is ambiguous for routing. The set tracks seen protocols and rejects the second occurrence.

Source

Thrown at console-ui-next/src/pages/newAgent/agent-console-model.ts:354

    }
    seen.add(key);
    return [{ uri, transport }];
  });
  return {
    protocol: required(editor.customProtocol, 'protocol'),
    protocolVersion: editor.customProtocolVersion.trim() || undefined,
    descriptorMediaType: required(editor.customDescriptorMediaType, 'descriptorMediaType'),
    nativeDescriptor,
    endpointSourceOrder: endpointSourceOrder(editor.endpointSourceMode),
    declaredEndpoints: declaredEndpoints.length > 0 ? declaredEndpoints : undefined,
  };
}

function validateUniqueProtocols(callInterfaces: AgentCallInterface[]): AgentCallInterface[] {
  const protocols = new Set<string>();
  for (const callInterface of callInterfaces) {
    if (protocols.has(callInterface.protocol)) {
      throw new Error(`protocol must be unique: ${callInterface.protocol}`);
    }
    protocols.add(callInterface.protocol);
  }
  return callInterfaces;
}

function serializeOptionalObject(value: string, name: string): string | undefined {
  if (!value.trim()) {
    return undefined;
  }
  const parsed = parseJson(value, name);
  if (parsed === null || Array.isArray(parsed) || typeof parsed !== 'object') {
    throw new Error(`${name} must be a JSON object`);
  }
  return JSON.stringify(parsed);
}

function serializeCallInterfaces(

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Ensure each callInterface has a distinct protocol value.
  2. If you need two endpoints for the same protocol, merge them into one interface with multiple declaredEndpoints.
  3. Dedupe the protocolEditors array before serializeCallInterfaces.

Example fix

// before
[{protocol:'A2A',...},{protocol:'A2A',...}]

// after
[{protocol:'A2A', declaredEndpoints:[{uri:'a',transport:'GRPC'},{uri:'b',transport:'GRPC'}]}]
Defensive patterns

Strategy: validation

Validate before calling

function dedupeProtocols(list) {
  const seen = new Set();
  for (const it of list) { if (seen.has(it.protocol)) throw new Error(`Duplicate protocol: ${it.protocol}`); seen.add(it.protocol); }
}

Type guard

function hasUniqueProtocols(list: { protocol: string }[]): boolean {
  return new Set(list.map((i) => i.protocol)).size === list.length;
}

Try / catch

try { validateUniqueProtocols(list); } catch (e) {
  if (/protocol must be unique/.test(e.message)) { toast.error('Each protocol may appear only once'); }
}

Prevention

When it happens

Trigger: User adds two structured protocol editors both configured as 'A2A', or duplicates a 'GRPC' entry. The protocolEditorKind list yields two interfaces with the same protocol string.

Common situations: Copy-pasting a protocol editor block to create a second endpoint but forgetting to change the protocol. Bulk import producing duplicates.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/88e2a81258a8516c. Report an issue: GitHub.