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
- Add a top-level servers array to the OpenAPI document with at least one valid URL entry.
- Provide OpenApiFunctionExecutionParameters.ServerUrlOverride with the base URL when importing.
- Load the document from a URL (kernel.ImportPluginFromOpenApiAsync with a URI) so the host is inferred as a fallback.
- 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
- Always declare a top-level servers array in the spec.
- Pass OpenApiFunctionExecutionParameters.ServerUrlOverride for local/missing-server specs.
- Load from a URL so the host is inferred as a fallback.
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
- The operation path resolves to '{requestAuthority}', which d
- No argument '{variable.Value.ArgumentName ?? variableName}'
- No valid server URL for operation {self.id}
- AZURE_OPENAI_ENDPOINT is not set.
- ApiManifest file not found: {filePath}
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/c3e85b98d6c81ee0.
Report an issue: GitHub.