microsoft/semantic-kernel · error · KernelException

Payload parameters cannot be retrieved from the '{operation.

Error message

Payload parameters cannot be retrieved from the '{operation.Id}' operation payload metadata because it is missing.

What it means

Thrown by RestApiOperationExtensions.GetPayloadParameters when payload parameters are requested from metadata (useParametersFromMetadata == true, i.e. EnableDynamicPayload == true) but operation.Payload is null. The artificial-parameter fallback path (payload/content-type) is only taken when useParametersFromMetadata is false, so a bodyless operation with metadata extraction enabled hits this guard. In the normal SK call chain the outer GetParameters method guards with 'if (operation.Payload is not null)' first, so this throw is reached only if that outer guard is bypassed (e.g. direct/future caller) - it is effectively a defensive invariant.

Source

Thrown at dotnet/src/Functions/Functions.OpenApi/Extensions/RestApiOperationExtensions.cs:109

        return null;
    }

    /// <summary>
    /// Retrieves the payload parameters for a given REST API operation.
    /// </summary>
    /// <param name="operation">The REST API operation to retrieve parameters for.</param>
    /// <param name="useParametersFromMetadata">Flag indicating whether to include parameters from metadata.
    /// If false or not specified, the 'payload' and 'content-type' parameters are added instead.</param>
    /// <param name="enableNamespacing">Flag indicating whether to namespace payload parameter names.</param>
    /// <param name="parameterFilter">Filter which can be used to eliminate or modify RestApiParameters.</param>
    /// <returns>A list of <see cref="RestApiParameter"/> representing the payload parameters.</returns>
    private static List<RestApiParameter> GetPayloadParameters(RestApiOperation operation, bool useParametersFromMetadata, bool enableNamespacing, RestApiParameterFilter? parameterFilter)
    {
        if (useParametersFromMetadata)
        {
            if (operation.Payload is null)
            {
                throw new KernelException($"Payload parameters cannot be retrieved from the '{operation.Id}' operation payload metadata because it is missing.");
            }

            // The 'text/plain' content type payload metadata does not contain parameter names.
            // So, returning artificial 'payload' parameter instead.
            if (operation.Payload.MediaType == MediaTypeTextPlain)
            {
                return [CreatePayloadArtificialParameter(operation)];
            }

            return GetParametersFromPayloadMetadata(operation, operation.Payload, operation.Payload.Properties, enableNamespacing, parameterFilter);
        }

        // Adding artificial 'payload' and 'content-type' in case parameters from payload metadata are not required.
        if (parameterFilter is not null)
        {
            return new RestApiParameter[]
            {
                CreatePayloadArtificialParameter(operation),

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. If you control EnableDynamicPayload, set it to false for operation sets without a body so the artificial payload+content-type params are used instead.
  2. Ensure you are using the standard kernel.ImportPluginFromOpenApiAsync flow, whose GetParameters already null-guards Payload before extracting metadata.
  3. Filter the OpenAPI document so bodyless operations are not subjected to payload-metadata extraction.
  4. If you call GetParameters directly, replicate the 'operation.Payload is not null' guard before requesting metadata params.

Example fix

// before - default EnableDynamicPayload (true) forces metadata extraction even for bodyless ops
var execParams = new OpenApiFunctionExecutionParameters();

// after - disable dynamic payload so artificial payload/content-type params are used
var execParams = new OpenApiFunctionExecutionParameters { EnableDynamicPayload = false };
Defensive patterns

Strategy: validation

Validate before calling

foreach (var op in operations)
{
    var hasBody = op.Payload is not null;
    var useMeta = enableDynamicPayload && hasBody; // mirror the GetParameters guard
}

Type guard

static bool NeedsPayloadMetadata(RestApiOperation op, bool enableDynamicPayload) => enableDynamicPayload && op.Payload is not null;

Try / catch

try { var ps = operation.GetParameters(enableDynamicPayload: false); }
catch (KernelException ex) when (ex.Message.Contains("payload metadata because it is missing"))
{ /* disable dynamic payload and retry with artificial params */ }

Prevention

When it happens

Trigger: An operation with no request body (a GET) being processed through a path that requests payload-from-metadata while Payload is null. In stock SK this is shielded by the GetParameters null-guard, so the realistic trigger is a custom caller invoking GetParameters plumbing in a way that skips the guard, or a future refactor that drops the outer check.

Common situations: Mixing operations of differing methods where some have bodies and some do not, with EnableDynamicPayload left at its default (true); a parameterFilter or custom execution path that enters payload extraction for a bodyless op.

Related errors


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