{"record":{"id":"bb6e4656bac35944","repo":"apache/skywalking","slug":"illegal-service-relation-entity-id","errorCode":null,"errorMessage":"Illegal Service Relation entity id","messagePattern":"Illegal Service Relation entity id","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/IDManager.java","lineNumber":89,"sourceCode":"            return define.sourceId + Const.RELATION_ID_CONNECTOR + define.destId;\n        }\n\n        /**\n         * @return encoded service hierarchy relation id\n         */\n        public static String buildServiceHierarchyRelationId(ServiceHierarchyRelationDefine define) {\n            return define.serviceId + Const.SERVICE_ID_CONNECTOR + define.serviceLayer.value() +\n                Const.RELATION_ID_CONNECTOR +\n                define.relatedServiceId + Const.SERVICE_ID_CONNECTOR + define.relatedServiceLayer.value();\n        }\n\n        /**\n         * @return service relation ID object decoded from {@link #buildRelationId(ServiceRelationDefine)} result\n         */\n        public static ServiceRelationDefine analysisRelationId(String entityId) {\n            String[] parts = entityId.split(Const.RELATION_ID_PARSER_SPLIT);\n            if (parts.length != 2) {\n                throw new RuntimeException(\"Illegal Service Relation entity id\");\n            }\n            return new ServiceRelationDefine(parts[0], parts[1]);\n        }\n\n        @RequiredArgsConstructor\n        @Getter\n        @EqualsAndHashCode\n        public static class ServiceIDDefinition {\n            private final String name;\n            /**\n             * TRUE means an agent installed or directly detected service. FALSE means a conjectural service\n             */\n            private final boolean isReal;\n        }\n\n        @RequiredArgsConstructor\n        @Getter\n        @EqualsAndHashCode","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/IDManager.java#L71-L107","documentation":"RuntimeException thrown by IDManager.ServiceID.analysisRelationId(String) when a service-relation entity id does not split into exactly 2 parts. Relation ids are built by buildRelationId as sourceServiceId + RELATION_ID_CONNECTOR + destServiceId; the decoder requires precisely two components and rejects anything else. Unlike the analysisId variants this throws bare RuntimeException, not UnexpectedException.","triggerScenarios":"Passing a service-hierarchy relation id (built by buildServiceHierarchyRelationId, which has 4 segments with layer values) into analysisRelationId by mistake; passing a hand-built string with 0, 1, or 3+ '.'-separated segments; passing null.","commonSituations":"Mixing up the two relation id formats after the service-hierarchy feature added buildServiceHierarchyRelationId; custom dashboards/queries joining ids with the wrong connector; corrupted storage rows.","solutions":["Confirm the id came from ServiceID.buildRelationId(ServiceRelationDefine); hierarchy ids need their own parsing, not this method","Log and inspect the entity id from the message; count segments against the expected 2","If data corruption is suspected, check the source storage rows for the relation type involved","Guard call sites with a segment-count check before invoking analysisRelationId"],"exampleFix":"// before (hierarchy id fed to the wrong parser)\nString id = IDManager.ServiceID.buildServiceHierarchyRelationId(def);\nIDManager.ServiceID.analysisRelationId(id); // 4 segments -> throws\n\n// after\nString id = IDManager.ServiceID.buildRelationId(\n    new ServiceRelationDefine(sourceSvcId, destSvcId));\nIDManager.ServiceID.analysisRelationId(id); // 2 segments -> ok","handlingStrategy":"type-guard","validationCode":"if (entityId == null || entityId.split(\"\\\\.\").length != 2) {\n    throw new IllegalArgumentException(\"Not a plain service-relation id (use the hierarchy parser for 4-part ids): \" + entityId);\n}","typeGuard":"boolean isPlainServiceRelationId(String id) {\n    return id != null && id.split(\"\\\\.\").length == 2;\n}","tryCatchPattern":"try {\n    ServiceRelationDefine def = IDManager.ServiceID.analysisRelationId(entityId);\n} catch (RuntimeException e) {\n    LOGGER.warn(\"Dropping malformed service relation entity id: {}\", entityId, e);\n}","preventionTips":["Tag relation ids with their kind at the call site so service vs hierarchy relations route to the right parser","Only analysisRelationId ids you obtained from buildRelationId yourself","Log the raw id on catch — the built-in message does not include it"],"tags":["id-management","data-corruption","parsing","oap-server"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}