microsoft/semantic-kernel · error · PluginInitializationError
Duplicate operationId: '{operationId}', path: '{path}', meth
Error message
Duplicate operationId: '{operationId}', path: '{path}', method: '{method}' What it means
The parser tracks every `operationId` it registers in `unique_operation_ids_registered`; if the same id appears twice it raises `PluginInitializationError` naming the id, path, and method. `operationId` doubles as the kernel function name, so duplicates would collide.
Source
Thrown at python/semantic_kernel/connectors/openapi_plugin/openapi_parser.py:260
server_entry = {
"url": server.get("url", "/"),
"variables": server.get("variables", {}),
"description": server.get("description", ""),
}
server_urls.append(server_entry)
else:
# Default server if none specified
server_urls = [{"url": "/", "variables": {}, "description": ""}]
for path, methods in paths.items():
for method, details in methods.items():
request_method = method.lower()
# Validate that operationId exists
if "operationId" not in details:
raise PluginInitializationError(f"operationId missing, path: '{path}', method: '{method}'")
operationId = details["operationId"]
if operationId in unique_operation_ids_registered:
raise PluginInitializationError(
f"Duplicate operationId: '{operationId}', path: '{path}', method: '{method}'"
)
unique_operation_ids_registered.add(operationId)
summary = details.get("summary", None)
description = details.get("description", None)
# Exclude operations whose path would resolve to a different effective request target
# than the one offered to the selection predicate: a dot-segment (encoded or literal)
# or a non-relative (absolute / authority-changing) path. Excluding them here keeps
# operation selection and request construction on one canonical target so such a path
# cannot bypass an include/exclude operation-selection filter.
if RestApiOperation._contains_dot_segment(path) or RestApiOperation._is_non_relative_path(path):
logger.warning(
f"Skipping operation {operationId} at path '{path}' because it does not resolve to a "
f"relative path on the configured server."
)
continueView on GitHub (pinned to c028a0c7dc)
Solutions
- Rename one of the duplicate `operationId`s to make it unique.
- Use a linter (Spectral `operation-operationId-unique`) to find all collisions.
- If merging specs, run a dedup pass that namespaces ids (e.g. prefix with the tag).
- Pre-process the spec to auto-disambiguate duplicates as `{operationId}_{method}_{path}`.
Example fix
# before
paths:
/pets:
get: { operationId: list, ... }
/owners:
get: { operationId: list, ... } # raises 1495
# after
paths:
/pets:
get: { operationId: listPets, ... }
/owners:
get: { operationId: listOwners, ... } Defensive patterns
Strategy: validation
Validate before calling
from collections import Counter
def duplicate_operation_ids(spec) -> list[str]:
ids = []
for path, methods in spec.get("paths", {}).items():
for method, d in methods.items():
oid = (d or {}).get("operationId")
if oid:
ids.append(oid)
return [oid for oid, n in Counter(ids).items() if n > 1]
dupes = duplicate_operation_ids(spec)
assert not dupes, dupes Type guard
def operation_ids_are_unique(spec) -> bool:
return not duplicate_operation_ids(spec) Try / catch
from semantic_kernel.exceptions import PluginInitializationError
try:
kernel.add_openapi_plugin(plugin_name="x", openapi_parsed_spec=spec)
except PluginInitializationError as e:
if "Duplicate operationId" in str(e):
# disambiguate ids, then retry
raise
raise Prevention
- Lint specs with Spectral `operation-operationId-unique`.
- Namespace ids by tag when merging specs.
- Generate ids deterministically from method+path.
- Review duplicate-id reports before publishing specs.
When it happens
Trigger: Two operations (different path/method, or aliased) sharing the same `operationId` string. Also possible after spec deduplication/merging that left duplicate ids.
Common situations: Copy-pasted operations; specs merged from multiple teams; aliases for the same endpoint; tools that auto-generate ids by method only (so `GET /a` and `GET /b` collide).
Related errors
- Parameter {name} is missing 'in' field
- Parameter {name} cannot have a 'content' field. Expected: sc
- Security scheme '{scheme_name}' is not defined in components
- operationId missing, path: '{path}', method: '{method}'
- This `RestApiParameter` instance is frozen and cannot be mod
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/e3241160a17362b1.
Report an issue: GitHub.