{"record":{"id":"be11ad904f18d8b7","repo":"apache/hadoop","slug":"pathhandle-only-available-for-files","errorCode":null,"errorMessage":"PathHandle only available for files","messagePattern":"PathHandle only available for files","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/RawLocalFileSystem.java","lineNumber":1233,"sourceCode":"          pathToFile(p).toPath(), BasicFileAttributeView.class);\n      FileTime fmtime = (mtime >= 0) ? FileTime.fromMillis(mtime) : null;\n      FileTime fatime = (atime >= 0) ? FileTime.fromMillis(atime) : null;\n      view.setTimes(fmtime, fatime, null);\n    } catch (NoSuchFileException e) {\n      throw new FileNotFoundException(\"File \" + p + \" does not exist\");\n    }\n  }\n\n  /**\n   * Hook to implement support for {@link PathHandle} operations.\n   * @param stat Referent in the target FileSystem\n   * @param opts Constraints that determine the validity of the\n   *            {@link PathHandle} reference.\n   */\n  protected PathHandle createPathHandle(FileStatus stat,\n      Options.HandleOpt... opts) {\n    if (stat.isDirectory() || stat.isSymlink()) {\n      throw new IllegalArgumentException(\"PathHandle only available for files\");\n    }\n    String authority = stat.getPath().toUri().getAuthority();\n    if (authority != null && !authority.equals(\"file://\")) {\n      throw new IllegalArgumentException(\"Wrong FileSystem: \" + stat.getPath());\n    }\n    Options.HandleOpt.Data data =\n        Options.HandleOpt.getOpt(Options.HandleOpt.Data.class, opts)\n            .orElse(Options.HandleOpt.changed(false));\n    Options.HandleOpt.Location loc =\n        Options.HandleOpt.getOpt(Options.HandleOpt.Location.class, opts)\n            .orElse(Options.HandleOpt.moved(false));\n    if (loc.allowChange()) {\n      throw new UnsupportedOperationException(\"Tracking file movement in \" +\n          \"basic FileSystem is not supported\");\n    }\n    final Path p = stat.getPath();\n    final Optional<Long> mtime = !data.allowChange()\n        ? Optional.of(stat.getModificationTime())","sourceCodeStart":1215,"sourceCodeEnd":1251,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/RawLocalFileSystem.java#L1215-L1251","documentation":"Thrown by RawLocalFileSystem.createPathHandle (the hook behind FileSystem.getPathHandle(FileStatus, HandleOpt...)) when the supplied FileStatus refers to a directory or a symbolic link. A PathHandle is an immutable reference to the *content* of a regular file, so directories and links have no meaningful handle in the local FileSystem implementation. The library fails fast with IllegalArgumentException rather than returning a handle that could never be resolved.","triggerScenarios":"Calling localFs.getPathHandle(stat, opts) where stat was obtained via getFileStatus()/listStatus() on a directory, or on a symlink (stat.isSymlink() == true). Also hit when code takes FileStatus from listStatus() of a directory tree and blindly calls getPathHandle() on each entry.","commonSituations":"Batch tools iterating a directory and requesting handles for every entry without filtering; passing a link status returned by getFileLinkStatus(); test code that uses a temp directory instead of a temp file.","solutions":["Filter to regular files first: only call getPathHandle when stat.isFile() && !stat.isSymlink()","If the referent is a symlink to a file, resolve the link target (fs.resolvePath/stat via FileContext) and build the handle from the target's FileStatus","Catch IllegalArgumentException at the call site and skip the entry when iterating heterogeneous listings"],"exampleFix":"// before\nFileStatus st = localFs.getFileStatus(p);\nPathHandle h = localFs.getPathHandle(st);\n\n// after\nFileStatus st = localFs.getFileStatus(p);\nif (st.isDirectory() || st.isSymlink()) {\n  throw new IllegalArgumentException(\"PathHandle requires a regular file: \" + p);\n}\nPathHandle h = localFs.getPathHandle(st);","handlingStrategy":"validation","validationCode":"FileStatus st = fs.getFileStatus(p);\nif (st.isDirectory() || st.isSymlink()) {\n  // skip or fail before asking for a handle\n  throw new IllegalArgumentException(\"PathHandle requires a regular file: \" + p);\n}\nPathHandle h = fs.getPathHandle(st, opts);","typeGuard":null,"tryCatchPattern":"try {\n  PathHandle h = fs.getPathHandle(stat);\n} catch (IllegalArgumentException e) {\n  // message: \"PathHandle only available for files\" -> wrong referent kind\n  log.warn(\"Skipping non-file: {}\", stat.getPath());\n}","preventionTips":["Always filter listings to stat.isFile() && !stat.isSymlink() before handle creation","Treat getPathHandle arguments as coming from exactly one FileSystem listing"],"tags":["hadoop","local-filesystem","pathhandle","invalid-argument"],"backgroundTag":"path-handle-invalid-referent","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}