{"record":{"id":"8b60c80513c85339","repo":"microsoft/semantic-kernel","slug":"operationid-missing-path-path-method-met","errorCode":null,"errorMessage":"operationId missing, path: '{path}', method: '{method}'","messagePattern":"operationId missing, path: '(.+?)', method: '(.+?)'","errorType":"exception","errorClass":"PluginInitializationError","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/openapi_plugin/openapi_parser.py","lineNumber":257,"sourceCode":"        elif servers:\n            # Process servers, ensuring we capture their variables\n            for server in servers:\n                server_entry = {\n                    \"url\": server.get(\"url\", \"/\"),\n                    \"variables\": server.get(\"variables\", {}),\n                    \"description\": server.get(\"description\", \"\"),\n                }\n                server_urls.append(server_entry)\n        else:\n            # Default server if none specified\n            server_urls = [{\"url\": \"/\", \"variables\": {}, \"description\": \"\"}]\n\n        for path, methods in paths.items():\n            for method, details in methods.items():\n                request_method = method.lower()\n                # Validate that operationId exists\n                if \"operationId\" not in details:\n                    raise PluginInitializationError(f\"operationId missing, path: '{path}', method: '{method}'\")\n                operationId = details[\"operationId\"]\n                if operationId in unique_operation_ids_registered:\n                    raise PluginInitializationError(\n                        f\"Duplicate operationId: '{operationId}', path: '{path}', method: '{method}'\"\n                    )\n                unique_operation_ids_registered.add(operationId)\n\n                summary = details.get(\"summary\", None)\n                description = details.get(\"description\", None)\n\n                # Exclude operations whose path would resolve to a different effective request target\n                # than the one offered to the selection predicate: a dot-segment (encoded or literal)\n                # or a non-relative (absolute / authority-changing) path. Excluding them here keeps\n                # operation selection and request construction on one canonical target so such a path\n                # cannot bypass an include/exclude operation-selection filter.\n                if RestApiOperation._contains_dot_segment(path) or RestApiOperation._is_non_relative_path(path):\n                    logger.warning(\n                        f\"Skipping operation {operationId} at path '{path}' because it does not resolve to a \"","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/openapi_plugin/openapi_parser.py#L239-L275","documentation":"While iterating `paths` x methods, the parser requires each operation object to carry an `operationId`. If the key is absent it raises `PluginInitializationError` with the path and method. The connector uses `operationId` as the function name, so it must be present and unique.","triggerScenarios":"An operation (path + HTTP method) in the spec without an `operationId` field. Common with specs authored for human-readable docs that relied on `summary` instead.","commonSituations":"Hand-written specs; specs exported from tools that omit `operationId` by default; OpenAPI 2.0 (Swagger) imports where `operationId` was optional; large specs where one endpoint was added quickly.","solutions":["Add a unique `operationId` to the offending operation in the spec.","Run a linter (e.g. Spectral with the `operation-operationId-unique` / `operationId` rules) to catch missing ids.","If you cannot edit the spec, pre-process it to synthesize ids (e.g. `{method}_{path}`) before loading.","Upgrade from Swagger 2.0 to OpenAPI 3.0 with a tool that backfills `operationId`."],"exampleFix":"# before\npaths:\n  /pets/{id}:\n    get:\n      summary: Get a pet   # no operationId -> raises 1494\n\n# after\npaths:\n  /pets/{id}:\n    get:\n      operationId: getPetById\n      summary: Get a pet","handlingStrategy":"validation","validationCode":"def ops_missing_id(spec) -> list[str]:\n    bad = []\n    for path, methods in spec.get(\"paths\", {}).items():\n        for method, d in methods.items():\n            if method.lower() not in {\"get\",\"post\",\"put\",\"patch\",\"delete\",\"head\",\"options\",\"trace\"}:\n                continue\n            if \"operationId\" not in d:\n                bad.append(f\"{method} {path}\")\n    return bad\n\nbad = ops_missing_id(spec)\nassert not bad, bad","typeGuard":"def has_operation_id(op_details) -> bool:\n    return isinstance(op_details, dict) and bool(op_details.get(\"operationId\"))","tryCatchPattern":"from semantic_kernel.exceptions import PluginInitializationError\n\ntry:\n    kernel.add_openapi_plugin(plugin_name=\"x\", openapi_parsed_spec=spec)\nexcept PluginInitializationError as e:\n    if \"operationId missing\" in str(e):\n        # synthesize ids, then retry\n        raise\n    raise","preventionTips":["Require `operationId` in your spec style guide.","Lint with Spectral's operationId rule in CI.","Auto-generate ids when importing Swagger 2.0.","Pre-process specs to synthesize `{method}_{path}` ids."],"tags":["openapi-plugin","spec-validation","semantic-kernel"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}