{"record":{"id":"f1a9867ccbd0cbdd","repo":"apache/dolphinscheduler","slug":"invalid-child-path","errorCode":null,"errorMessage":"Invalid child path ","messagePattern":"Invalid child path ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/KeyUtils.java","lineNumber":41,"sourceCode":"\nimport org.apache.commons.lang3.StringUtils;\n\nimport lombok.experimental.UtilityClass;\n\n@UtilityClass\npublic class KeyUtils {\n\n    /**\n     * Whether the path is the parent path of the child\n     * <p> Only the parentPath is the parent path of the childPath, return true\n     * <p> If the parentPath is equal to the childPath, return false\n     */\n    public static boolean isParent(final String parentPath, final String childPath) {\n        if (StringUtils.isEmpty(parentPath)) {\n            throw new IllegalArgumentException(\"Invalid parent path \" + parentPath);\n        }\n        if (StringUtils.isEmpty(childPath)) {\n            throw new IllegalArgumentException(\"Invalid child path \" + childPath);\n        }\n        final String[] parentSplit = removeLastSlash(parentPath).split(RegistryConstants.PATH_SEPARATOR);\n        final String[] childSplit = removeLastSlash(childPath).split(RegistryConstants.PATH_SEPARATOR);\n        // If the parent path is longer than or equals the child path, it is impossible to be the parent path of the\n        // child path\n        if (parentSplit.length >= childSplit.length) {\n            return false;\n        }\n        for (int i = 0; i < parentSplit.length; i++) {\n            if (!parentSplit[i].equals(childSplit[i])) {\n                return false;\n            }\n        }\n        return true;\n\n    }\n\n    public static boolean isSamePath(final String path1, final String path2) {","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/KeyUtils.java#L23-L59","documentation":"KeyUtils.isParent validates that both parentPath and childPath are non-empty strings starting with the registry path separator ('/') before comparing path segments. This specific throw fires when childPath is null or empty, refusing to compute a parent/child relationship against an invalid child path. The JDBC registry uses this helper for subscription and tree operations, so a malformed path would silently corrupt the segment comparison if not rejected.","triggerScenarios":"Calling KeyUtils.isParent(parentPath, \"\") or isParent(parentPath, null); passing a path variable that was never initialized or trimmed to empty from configuration or an event payload; calling higher-level JDBC registry APIs (e.g. subscribe/addListener paths) that delegate to isParent with a blank path.","commonSituations":"Registry paths read from misconfigured properties (empty registry path prefix), deserialized subscription records with missing path fields, or string manipulation that stripped the path down to empty before calling isParent.","solutions":["Ensure the child path is a non-empty string starting with '/' before calling isParent","Validate/trim the source of the path (config value, event payload) and fail early with a clear message","Pass a normalized constant such as '/' when the caller genuinely means the root path"],"exampleFix":"// before\nboolean parent = KeyUtils.isParent(\"/nodes\", childPath); // childPath may be \"\"\n// after\nif (StringUtils.isNotEmpty(childPath) && childPath.startsWith(\"/\")) {\n    boolean parent = KeyUtils.isParent(\"/nodes\", childPath);\n}","handlingStrategy":"validation","validationCode":"if (childPath == null || !childPath.startsWith(\"/\")) { throw new IllegalArgumentException(\"childPath must be an absolute non-empty path\"); }","typeGuard":"boolean isValidRegistryPath(String p) { return p != null && !p.isEmpty() && p.startsWith(\"/\"); }","tryCatchPattern":"try { KeyUtils.isParent(parent, child); } catch (IllegalArgumentException e) { log.warn(\"Bad path: {}\", e.getMessage()); }","preventionTips":["Always build registry paths with a central helper that guarantees a leading '/'","Never pass user/config-supplied paths without trimming and validating","Default empty paths to root '/' explicitly"],"tags":["registry","argument-validation","path"],"backgroundTag":"invalid-argument-value","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}