{"record":{"id":"33e41127539901fd","repo":"apache/hadoop","slug":"no-parent-of-s","errorCode":null,"errorMessage":"No parent of %s","messagePattern":"No parent of (.+?)","errorType":"exception","errorClass":"PathNotFoundException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/binding/RegistryPathUtils.java","lineNumber":189,"sourceCode":"      // empty path. Return \"\"\n      return \"\";\n    } else {\n      return splits.get(splits.size() - 1);\n    }\n  }\n\n  /**\n   * Get the parent of a path\n   * @param path path to look at\n   * @return the parent path\n   * @throws PathNotFoundException if the path was at root.\n   */\n  public static String parentOf(String path) throws PathNotFoundException {\n    List<String> elements = split(path);\n\n    int size = elements.size();\n    if (size == 0) {\n      throw new PathNotFoundException(\"No parent of \" + path);\n    }\n    if (size == 1) {\n      return \"/\";\n    }\n    elements.remove(size - 1);\n    StringBuilder parent = new StringBuilder(path.length());\n    for (String element : elements) {\n      parent.append(\"/\");\n      parent.append(element);\n    }\n    return parent.toString();\n  }\n\n  /**\n   * Perform any formatting for the registry needed to convert\n   * non-simple-DNS elements\n   * @param element element to encode\n   * @return an encoded string","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/binding/RegistryPathUtils.java#L171-L207","documentation":"RegistryPathUtils.parentOf splits a path into elements and returns the parent; at the root ('/' or '' — split yields zero elements) there is no parent, so it throws PathNotFoundException ('No parent of <path>'). Note split(\"\") and split(\"/\") both return an empty list.","triggerScenarios":"Walking up the tree with parentOf in a loop and calling it once more when the path is already '/'; calling parentOf(\"/\") or parentOf(\"\") directly; loop conditions like while (path != null) instead of while (!path.equals(\"/\")).","commonSituations":"Recursive delete/list algorithms over registry subtrees; code ported from filesystem utilities that expect parent-of-root to return null instead of throwing.","solutions":["Terminate the walk at root explicitly: while (!\"/\".equals(path)) { ...; path = RegistryPathUtils.parentOf(path); }","Guard the call: if RegistryPathUtils.split(path).isEmpty(), handle the root case before calling parentOf","Catch PathNotFoundException from parentOf as the 'reached root' signal and stop the walk"],"exampleFix":"// before\nString p = path;\nwhile (p != null) {\n  visit(p);\n  p = RegistryPathUtils.parentOf(p); // throws at \"/\"\n}\n\n// after\nString p = path;\nwhile (p != null && !RegistryPathUtils.split(p).isEmpty()) {\n  visit(p);\n  p = RegistryPathUtils.parentOf(p);\n}","handlingStrategy":"validation","validationCode":"String current = path;\nwhile (!RegistryPathUtils.split(current).isEmpty()) { // empty at \"/\" or \"\"\n  visit(current);\n  current = RegistryPathUtils.parentOf(current);\n}","typeGuard":null,"tryCatchPattern":"try {\n  parent = RegistryPathUtils.parentOf(path);\n} catch (PathNotFoundException e) {\n  // path was root — no parent exists; stop walking up\n  return Optional.empty();\n}","preventionTips":["Terminate upward walks at '/' explicitly rather than at null","Remember split(\"/\") is empty — root has no elements and no parent","Treat PathNotFoundException from parentOf as a normal 'reached root' signal, not a corruption event"],"tags":["registry","zookeeper","path","tree-traversal"],"backgroundTag":"root-path-no-parent","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}