{"record":{"id":"7af089177f8d741a","repo":"apache/hadoop","slug":"path-path-is-not-a-symbolic-link-7af089","errorCode":null,"errorMessage":"Path ${path} is not a symbolic link","messagePattern":"Path (.+?) is not a symbolic link","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/HdfsNamedFileStatus.java","lineNumber":108,"sourceCode":"    super.setOwner(owner);\n  }\n\n  @Override\n  public void setGroup(String group) {\n    super.setOwner(group);\n  }\n\n  @Override\n  public boolean isSymlink() {\n    return uSymlink != null && uSymlink.length > 0;\n  }\n\n  @Override\n  public Path getSymlink() throws IOException {\n    if (isSymlink()) {\n      return new Path(DFSUtilClient.bytes2String(getSymlinkInBytes()));\n    }\n    throw new IOException(\"Path \" + getPath() + \" is not a symbolic link\");\n  }\n\n  @Override\n  public void setPermission(FsPermission permission) {\n    super.setPermission(permission);\n  }\n\n  /**\n   * Get the Java UTF8 representation of the local name.\n   *\n   * @return the local name in java UTF8\n   */\n  @Override\n  public byte[] getLocalNameInBytes() {\n    return uPath;\n  }\n\n  @Override","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/HdfsNamedFileStatus.java#L90-L126","documentation":"Identical guard to HdfsLocatedFileStatus: HdfsNamedFileStatus.getSymlink() throws IOException when the entry carries no symlink target bytes (isSymlink() == false). HdfsNamedFileStatus is the non-located variant of HDFS file status; the contract is the same as FileStatus.getSymlink().","triggerScenarios":"Calling getSymlink() on statuses returned by getFileStatus/listStatus (non-located path) for a plain file or directory, or on a symlink entry with an empty target array.","commonSituations":"Shared handling of FileStatus objects where some branches forget the isSymlink() check; unit tests with hand-constructed statuses lacking target bytes.","solutions":["Check isSymlink() before getSymlink().","Write a small helper that returns Optional<Path> of the target and use it everywhere.","In tests, construct symlink statuses with a non-empty target byte array."],"exampleFix":"// before\nPath target = status.getSymlink();\n\n// after\nPath target = status.isSymlink() ? status.getSymlink() : null;","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static Optional<Path> symlinkTarget(FileStatus st) {\n  return (st != null && st.isSymlink()) ? Optional.of(st.getSymlink()) : Optional.empty();\n}","tryCatchPattern":"try { Path t = st.getSymlink(); }\ncatch (IOException e) { /* not a symlink — guard with isSymlink() instead */ }","preventionTips":["Use isSymlink() as the gate before reading targets in shared FileStatus code.","Keep one project-wide helper for target extraction.","In tests, build symlink statuses with non-empty target arrays so isSymlink() is true."],"tags":["hdfs","symlink","file-status","api-misuse"],"backgroundTag":"invalid-state-access","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}