microsoft/semantic-kernel · error · FunctionExecutionException

Payload can't be built dynamically due to the missing payloa

Error message

Payload can't be built dynamically due to the missing payload metadata.

What it means

`OpenApiRunner.build_json_payload` builds a JSON body dynamically only when `enable_dynamic_payload` is True. In that mode it requires non-null `payload_metadata`; if the operation has no payload metadata (e.g. the request body could not be parsed into a `RestApiPayload`), it raises `FunctionExecutionException`.

Source

Thrown at python/semantic_kernel/connectors/openapi_plugin/openapi_runner.py:73

    def build_full_url(self, base_url, query_string):
        """Build the full URL."""
        url_parts = list(urlparse(base_url))
        url_parts[4] = query_string
        return urlunparse(url_parts)

    def build_operation_url(
        self, operation: RestApiOperation, arguments: KernelArguments, server_url_override=None, api_host_url=None
    ):
        """Build the operation URL."""
        url = operation.build_operation_url(arguments, server_url_override, api_host_url)
        return self.build_full_url(url, operation.build_query_string(arguments))

    def build_json_payload(self, payload_metadata: RestApiPayload, arguments: dict[str, Any]) -> tuple[str, str]:
        """Build the JSON payload."""
        if self.enable_dynamic_payload:
            if payload_metadata is None:
                raise FunctionExecutionException(
                    "Payload can't be built dynamically due to the missing payload metadata."
                )

            payload = self.build_json_object(payload_metadata.properties, arguments)
            content = json.dumps(payload)
            return content, payload_metadata.media_type

        argument = arguments.get(self.payload_argument_name)
        if not isinstance(argument, str):
            raise FunctionExecutionException(f"No payload is provided by the argument '{self.payload_argument_name}'.")

        return argument, argument

    def build_json_object(self, properties, arguments, property_namespace=None):
        """Build the JSON payload object."""
        result = {}

        for property_metadata in properties:

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Disable `enable_dynamic_payload` for that operation and pass the raw body string via `payload_argument_name`.
  2. Fix the spec so the operation's request body has a supported media type (so payload metadata is built).
  3. Exclude the operation from registration if it cannot conform.
  4. Confirm the operation actually has a request body in the parsed metadata before invoking with dynamic payload.

Example fix

# before
runner = OpenApiRunner(parsed_openapi_document=spec, enable_dynamic_payload=True)
await runner.run_operation(op_without_payload_metadata, args, options)  # raises 1496

# after
runner = OpenApiRunner(parsed_openapi_document=spec, enable_dynamic_payload=False)
args[runner.payload_argument_name] = json.dumps({"a": 1})
await runner.run_operation(op, args, options)
Defensive patterns

Strategy: type-guard

Validate before calling

def can_build_dynamically(runner, operation) -> bool:
    return bool(runner.enable_dynamic_payload and operation.payload is not None)

# before invoking with dynamic payload
assert can_build_dynamically(runner, op), (
    f"{op.id} has no payload metadata; disable dynamic payload or pass a body string"
)

Type guard

def has_payload_metadata(operation) -> bool:
    return getattr(operation, "payload", None) is not None

Try / catch

from semantic_kernel.exceptions import FunctionExecutionException

try:
    await runner.run_operation(op, args, options)
except FunctionExecutionException as e:
    if "missing payload metadata" in str(e):
        # fall back to passing a raw body string
        args[runner.payload_argument_name] = json.dumps(body_dict)
        await runner.run_operation(op, args, options)
    else:
        raise

Prevention

When it happens

Trigger: Calling an operation that has a request body with `enable_dynamic_payload=True`, but the parser could not build `RestApiPayload` metadata for it (often because the media type was unsupported — see 1492 — so payload metadata is `None`).

Common situations: Enabling dynamic payload building globally but invoking an operation whose body uses an unsupported media type; mixing JSON and XML endpoints under one plugin with dynamic payload on; operations whose request body was skipped during parsing.

Related errors


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