microsoft/semantic-kernel · error · InvalidOperationException

Server url is not defined for operation {this.Id}

Error message

Server url is not defined for operation {this.Id}

What it means

Thrown by GetServerUrl when there is no serverUrlOverride, the operation's Servers collection is empty (or its first entry has no Url), and no apiHostUrl is available (i.e. the document was not loaded from a URI). With no source of a base URL, the operation's absolute request URL cannot be determined.

Source

Thrown at dotnet/src/Functions/Functions.OpenApi/Model/RestApiOperation.cs:429

                    serverUrlString = serverUrlString.Replace($"{{{variableName}}}", Uri.EscapeDataString(strValue));
                }
                // Use the default value if no argument is provided.
                else if (variable.Value.Default is not null)
                {
                    serverUrlString = serverUrlString.Replace($"{{{variableName}}}", variable.Value.Default);
                }
                // Throw an exception if there's no value for the variable.
                else
                {
                    throw new KernelException($"No argument '{variable.Value.ArgumentName ?? variableName}' provided for the '{variableName}' server variable of the operation - '{this.Id}'.");
                }
            }
        }
        else
        {
            serverUrlString =
                apiHostUrl?.AbsoluteUri ??
                throw new InvalidOperationException($"Server url is not defined for operation {this.Id}");
        }

        // Make sure base url ends with trailing slash
        if (!serverUrlString.EndsWith("/", StringComparison.OrdinalIgnoreCase))
        {
            serverUrlString += "/";
        }

        return new Uri(serverUrlString);
    }

    private static readonly Dictionary<RestApiParameterStyle, Func<RestApiParameter, JsonNode, string>> s_parameterSerializers = new()
    {
        { RestApiParameterStyle.Simple, SimpleStyleParameterSerializer.Serialize },
        { RestApiParameterStyle.Form, FormStyleParameterSerializer.Serialize },
        { RestApiParameterStyle.SpaceDelimited, SpaceDelimitedStyleParameterSerializer.Serialize },
        { RestApiParameterStyle.PipeDelimited, PipeDelimitedStyleParameterSerializer.Serialize }
    };

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Add a top-level servers array to the OpenAPI document with at least one valid URL entry.
  2. Provide OpenApiFunctionExecutionParameters.ServerUrlOverride with the base URL when importing.
  3. Load the document from a URL (kernel.ImportPluginFromOpenApiAsync with a URI) so the host is inferred as a fallback.
  4. Verify servers[0].url is non-empty in the spec.

Example fix

// before - no servers in spec, no override, loaded from a stream
var plugin = await kernel.CreatePluginFromOpenApiAsync("p", stream);

// after - supply a server URL override
var exec = new OpenApiFunctionExecutionParameters { ServerUrlOverride = new Uri("https://api.example.com") };
var plugin = await OpenApiKernelPluginFactory.CreateFromOpenApiAsync("p", stream, exec);
Defensive patterns

Strategy: validation

Validate before calling

var hasServer = doc.Servers.Count > 0 && !string.IsNullOrWhiteSpace(doc.Servers[0].Url);
var hasOverride = execParams?.ServerUrlOverride is not null;
var hasHost = documentUri is not null;
if (!hasServer && !hasOverride && !hasHost)
    throw new InvalidOperationException("No server URL available; add a servers entry or set ServerUrlOverride.");

Type guard

static bool HasResolvableServer(OpenApiDocument doc, Uri? overrideUrl, Uri? hostUri)
    => overrideUrl is not null
       || (doc.Servers.Count > 0 && !string.IsNullOrWhiteSpace(doc.Servers[0].Url))
       || hostUri is not null;

Try / catch

try { var url = operation.BuildOperationUrl(arguments, execParams?.ServerUrlOverride, apiHostUrl); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Server url is not defined"))
{ logger.LogError(ex, "No server configured; set ServerUrlOverride."); throw; }

Prevention

When it happens

Trigger: Importing an OpenAPI document that has no 'servers' field and was loaded from a local stream (so there is no document host to fall back on), and no ServerUrlOverride provided in OpenApiFunctionExecutionParameters. The first Servers entry having a null Url also triggers this.

Common situations: A local OpenAPI file missing the top-level 'servers' array (common in hand-authored or older 2.0 specs); loading from a Stream/byte[] rather than a URL so SK cannot infer a host; a spec where servers[0].url is blank.

Related errors


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