{"record":{"id":"f0757850ee03e534","repo":"apache/skywalking","slug":"openapi-definition-file-file-getabsolutepath","errorCode":null,"errorMessage":"OpenAPI definition file: {file.getAbsolutePath()} found in root directory, but doesn't include x-sw-service-name extensive definition in the file.","messagePattern":"OpenAPI definition file: (.+?) found in root directory, but doesn't include x-sw-service-name extensive definition in the file\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"critical","filePath":"oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/config/group/openapi/EndpointGroupingRuleReader4Openapi.java","lineNumber":139,"sourceCode":"            }\n            Reader reader = new StringReader(openapiDefs);\n            Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));\n            Map openapiData = yaml.load(reader);\n            if (openapiData != null) {\n                serviceOpenapiDefMap.computeIfAbsent(getServiceName(serviceName, openapiData), k -> new ArrayList<>())\n                                    .add(openapiData);\n            }\n        });\n\n        return serviceOpenapiDefMap;\n    }\n\n    private String getServiceName(String openapiDefPath, File file, Map openapiData) {\n        String serviceName = (String) openapiData.get(\"x-sw-service-name\");\n        if (StringUtil.isEmpty(serviceName)) {\n            File directory = new File(file.getParent());\n            if (openapiDefPath.equals(directory.getName())) {\n                throw new IllegalArgumentException(\n                    \"OpenAPI definition file: \" + file.getAbsolutePath() + \" found in root directory, but doesn't include x-sw-service-name extensive definition in the file.\");\n            }\n            serviceName = directory.getName();\n        }\n\n        return serviceName;\n    }\n\n    private String getServiceName(String defaultServiceName, Map openapiData) {\n        String serviceName = (String) openapiData.get(\"x-sw-service-name\");\n        if (StringUtil.isEmpty(serviceName)) {\n            serviceName = defaultServiceName;\n        }\n\n        return serviceName;\n    }\n\n    private boolean isTemplatePath(String pathString) {","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/config/group/openapi/EndpointGroupingRuleReader4Openapi.java#L121-L157","documentation":"When loading OpenAPI definitions for endpoint grouping, EndpointGroupingRuleReader4Openapi derives the service name either from the 'x-sw-service-name' extension field in the file or, failing that, from the name of the directory containing the file. If neither exists — the file sits directly in the configured root directory AND lacks x-sw-service-name — the service name is ambiguous, so the reader throws IllegalArgumentException.","triggerScenarios":"An OpenAPI definition file placed in the root of the openapi definitions directory (its parent directory equals the configured root path, checked via openapiDefPath.equals(directory.getName())) without an 'x-sw-service-name' field in its top-level map.","commonSituations":"Dropping petstore.yaml straight into the open-apis folder instead of a per-service subfolder; enabling openapi grouping (core.openapi-endpoint-grouping) on an existing folder of flat YAML files; removing the extension field during spec cleanup or regeneration from an upstream spec that never had it.","solutions":["Move the file into a subdirectory named after its service (e.g. open-apis/my-service/service.yaml); the directory name becomes the service name.","Or add the extension field to the spec: 'x-sw-service-name: my-service' at the document root.","If multiple specs belong to one service, keep them in that service's subdirectory or give each the same x-sw-service-name.","Restart OAP after fixing."],"exampleFix":"# open-apis/root-level-spec.yaml — before (in root dir, no extension)\nopenapi: 3.0.0\ninfo:\n  title: demo\n\n# after (option A: keep in root, add extension)\nopenapi: 3.0.0\ninfo:\n  title: demo\nx-sw-service-name: demo-service\n\n# after (option B: move file to open-apis/demo-service/demo.yaml)","handlingStrategy":"validation","validationCode":"// Pre-check openapi dir layout before boot\nPath root = Path.of(openapiDir);\ntry (Stream<Path> files = Files.list(root)) {\n    for (Path p : files.filter(Files::isRegularFile).collect(Collectors.toList())) {\n        Map spec = yaml.load(Files.readString(p));\n        boolean hasName = spec != null && spec.containsKey(\"x-sw-service-name\");\n        if (!hasName) throw new ConfigException(\"root-level spec lacks x-sw-service-name: \" + p);\n    }\n}","typeGuard":null,"tryCatchPattern":"Not applicable — startup config error; fix file placement or spec.","preventionTips":["Adopt a convention: one subdirectory per service under the openapi root.","Add 'x-sw-service-name' in your spec-generation pipeline so it survives regeneration.","Validate the folder structure in CI before deploying OAP config."],"tags":["configuration","openapi","endpoint-grouping","yaml","startup"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}