microsoft/semantic-kernel · error · FunctionExecutionException

Error parsing OpenAPI document: {openapi_document_path}

Error message

Error parsing OpenAPI document: {openapi_document_path}

What it means

`OpenApiParser.parse()` returned `None`, meaning the OpenAPI document at `openapi_document_path` could not be parsed into a usable spec. The manager then refuses to continue and raises `FunctionExecutionException` so an empty/broken plugin is never registered silently.

Source

Thrown at python/semantic_kernel/connectors/openapi_plugin/openapi_manager.py:66

    """
    parsed_doc: dict[str, Any] | Any = None
    if openapi_parsed_spec is not None:
        parsed_doc = openapi_parsed_spec
    else:
        if openapi_document_path is None:
            raise FunctionExecutionException(
                "Either `openapi_document_path` or `openapi_parsed_spec` must be provided."
            )

        # Parse the document from the given path
        parser = OpenApiParser()
        parsed_doc = parser.parse(
            openapi_document_path,
            enable_file_ref_resolution=(execution_settings.enable_file_ref_resolution if execution_settings else False),
            enable_http_ref_resolution=(execution_settings.enable_http_ref_resolution if execution_settings else False),
        )
        if parsed_doc is None:
            raise FunctionExecutionException(f"Error parsing OpenAPI document: {openapi_document_path}")

    parser = OpenApiParser()
    operations = parser.create_rest_api_operations(parsed_doc, execution_settings=execution_settings)

    global_security_requirements = parsed_doc.get("security", [])

    auth_callback = None
    if execution_settings and execution_settings.auth_callback:
        auth_callback = execution_settings.auth_callback

    openapi_runner = OpenApiRunner(
        parsed_openapi_document=parsed_doc,
        auth_callback=auth_callback,
        http_client=execution_settings.http_client if execution_settings else None,
        enable_dynamic_payload=execution_settings.enable_dynamic_payload if execution_settings else True,
        enable_payload_namespacing=execution_settings.enable_payload_namespacing if execution_settings else False,
        server_url_validation_options=ServerUrlValidationOptions(
            allowed_base_urls=execution_settings.server_url_validation_allowed_base_urls,

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Open the file and validate it is a well-formed OpenAPI document (try `swagger-cli validate` / `openapi-spec-validator`).
  2. Confirm the path points at the intended spec and the file is non-empty.
  3. If `$ref` resolution fails, enable `enable_file_ref_resolution`/`enable_http_ref_resolution` in the execution settings or bundle the spec first.
  4. Check the parser's own logs for the underlying parse error before retrying.

Example fix

# before
kernel.add_openapi_plugin(plugin_name="x", openapi_document_path="/specs/broken.yaml")  # raises 1485

# after
# validate first
import yaml, pathlib
spec = yaml.safe_load(pathlib.Path("/specs/x.yaml").read_text())
assert spec and "paths" in spec
kernel.add_openapi_plugin(plugin_name="x", openapi_parsed_spec=spec)
Defensive patterns

Strategy: validation

Validate before calling

import yaml, json, pathlib

def load_and_validate_spec(path: str) -> dict:
    text = pathlib.Path(path).read_text()
    spec = yaml.safe_load(text) if path.endswith((".yaml", ".yml")) else json.loads(text)
    if not isinstance(spec, dict) or "paths" not in spec:
        raise ValueError(f"{path} did not parse into a valid OpenAPI document")
    return spec

spec = load_and_validate_spec(path)
kernel.add_openapi_plugin(plugin_name="x", openapi_parsed_spec=spec)

Type guard

def looks_like_openapi(spec) -> bool:
    return isinstance(spec, dict) and ("openapi" in spec or "swagger" in spec) and "paths" in spec

Try / catch

from semantic_kernel.exceptions import FunctionExecutionException

try:
    kernel.add_openapi_plugin(plugin_name="x", openapi_document_path=path)
except FunctionExecutionException as e:
    if "Error parsing OpenAPI document" in str(e):
        # validate file with an external linter, fix, then retry
        raise ConfigError(f"Unparseable spec at {path}") from e
    raise

Prevention

When it happens

Trigger: The file exists and is readable but its contents are not a valid OpenAPI document (malformed YAML/JSON, wrong structure, `$ref` resolution failures, or an empty file), causing `parse()` to yield `None`.

Common situations: Pointing at the wrong file (e.g. a README or a JSON error response); a half-downloaded spec; a spec with unresolved `$ref`s when ref resolution is disabled; a corrupted file in CI artifact; YAML indentation errors.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/6a8041eeac193822. Report an issue: GitHub.