apache/shenyu · error · IllegalArgumentException
OpenAPI document is missing the top-level 'servers' field…
Error message
OpenAPI document is missing the top-level 'servers' field, which is required for MCP import. Please add a servers section, e.g.: servers: [{ url: 'http://localhost:8080' }] What it means
buildMetaDataRegisterDTO() throws IllegalArgumentException when the parsed OpenAPI document has no top-level 'servers' array (or it is empty). The servers field supplies the base URL used to build MCP tool metadata; without it the gateway cannot construct the upstream target. The message includes an example servers section to guide the user.
Solutions
- Add a top-level servers array to the OpenAPI document, e.g. servers: [{url: 'http://localhost:8080'}], with the real backend address.
- Regenerate/export the spec from the source tool with server information included.
- If migrating from Swagger 2.0, convert host/basePath into an OpenAPI 3.0 servers entry.
Example fix
// before (openapi.json)
{
"openapi": "3.0.1",
"info": { "title": "api", "version": "1.0" }
}
// after
{
"openapi": "3.0.1",
"info": { "title": "api", "version": "1.0" },
"servers": [{ "url": "http://localhost:8080" }]
} Defensive patterns
Strategy: validation
Validate before calling
JsonElement root = JsonParser.parseString(swaggerJson).getAsJsonObject();
if (!root.has("servers") || !root.getAsJsonArray("servers").iterator().hasNext()) {
throw new IllegalArgumentException("openapi doc needs servers: [{url: ...}] before MCP import");
} Type guard
boolean hasServers(OpenAPI api) {
return api != null && api.getServers() != null && !api.getServers().isEmpty()
&& api.getServers().get(0).getUrl() != null && !api.getServers().get(0).getUrl().isBlank();
} Try / catch
try {
service.importMcpConfig(request);
} catch (IllegalArgumentException e) {
return ResponseEntity.badRequest().body("Fix your OpenAPI doc: " + e.getMessage());
} Prevention
- Always include a servers array when exporting OpenAPI specs used for MCP import.
- Lint specs in CI to require non-empty servers when targeting MCP registration.
- Convert Swagger 2.0 host/basePath to OpenAPI 3.0 servers when migrating specs.
- Use absolute URLs in servers rather than relative paths.
When it happens
Trigger: Importing an MCP config whose swagger/OpenAPI JSON lacks `servers: [{url: ...}]` at the document root — the code checks openapi.getServers() for null/empty before reading servers.get(0).getUrl().
Common situations: OpenAPI documents generated for documentation only (no server info); swagger files copied from specs where servers were stripped; specs using relative server URLs or relying on host/basePath from Swagger 2.0 instead of OpenAPI 3.0 servers.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- OpenAPI pathKey cannot be null or empty
- OpenAPI methodType cannot be null or empty
- parameter error
- Unsupported Swagger version, only Swagger 2.0 and OpenAPI…
- Invalid input JSON format
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/aa89541f1f399fb6.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SwaggerImportServiceImpl.java:215
shenyuMcpRequestConfig.setBodyToJson("false");
tool.setRequestConfig(shenyuMcpRequestConfig);
tool.setToolName(operation.getOperationId());
tool.setEnable(true);
PathItem.HttpMethod httpMethod = opEntry.getKey();
tool.setMethod(httpMethod.name().toLowerCase());
toolMap.put(fullPath, tool);
}
maps.add(toolMap);
}
return result;
}
private MetaDataRegisterDTO buildMetaDataRegisterDTO(final OpenAPI openapi, final String selectorName,
final ShenyuMcpTool shenyuMcpTool, final String contentPath,
final String namespaceId) {
if (Objects.isNull(openapi.getServers()) || openapi.getServers().isEmpty()) {
throw new IllegalArgumentException("OpenAPI document is missing the top-level 'servers' field, which is required for MCP import. "
+ "Please add a servers section, e.g.: servers: [{ url: 'http://localhost:8080' }]");
}
String urlString = openapi.getServers().get(0).getUrl();
URL url;
try {
url = new URL(urlString);
} catch (MalformedURLException e) {
LOG.error("url error");
throw new RuntimeException(e);
}
String host = url.getHost();
int port = url.getPort();
Operation operation = shenyuMcpTool.getOperation();
String parameterTypes = Objects.isNull(operation.getParameters())
? ""
: operation.getParameters()
.stream()
.map(Parameter::getIn)View on GitHub (pinned to 567142e072)