{"record":{"id":"311b0e4ceaf53725","repo":"apache/hadoop","slug":"could-not-determine-filetype-for-path","errorCode":null,"errorMessage":"Could not determine filetype for: {path}","messagePattern":"Could not determine filetype for: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/client/HttpFSFileSystem.java","lineNumber":187,"sourceCode":"\n  public static final String UPLOAD_CONTENT_TYPE= \"application/octet-stream\";\n\n  public static final String SNAPSHOT_JSON = \"Path\";\n\n  public enum FILE_TYPE {\n    FILE, DIRECTORY, SYMLINK;\n\n    public static FILE_TYPE getType(FileStatus fileStatus) {\n      if (fileStatus.isFile()) {\n        return FILE;\n      }\n      if (fileStatus.isDirectory()) {\n        return DIRECTORY;\n      }\n      if (fileStatus.isSymlink()) {\n        return SYMLINK;\n      }\n      throw new IllegalArgumentException(\"Could not determine filetype for: \" +\n                                         fileStatus.getPath());\n    }\n  }\n\n  public static final String FILE_STATUSES_JSON = \"FileStatuses\";\n  public static final String FILE_STATUS_JSON = \"FileStatus\";\n  public static final String FS_STATUS_JSON = \"FsStatus\";\n  public static final String PATH_SUFFIX_JSON = \"pathSuffix\";\n  public static final String TYPE_JSON = \"type\";\n  public static final String LENGTH_JSON = \"length\";\n  public static final String OWNER_JSON = \"owner\";\n  public static final String GROUP_JSON = \"group\";\n  public static final String PERMISSION_JSON = \"permission\";\n  public static final String ACCESS_TIME_JSON = \"accessTime\";\n  public static final String MODIFICATION_TIME_JSON = \"modificationTime\";\n  public static final String BLOCK_SIZE_JSON = \"blockSize\";\n  public static final String CHILDREN_NUM_JSON = \"childrenNum\";\n  public static final String FILE_ID_JSON = \"fileId\";","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/client/HttpFSFileSystem.java#L169-L205","documentation":"HttpFSFileSystem.FILE_TYPE.getType (HttpFSFileSystem.java:180-191) maps a Hadoop FileStatus to the JSON type field of the WebHDFS/HttpFS response by probing isFile(), then isDirectory(), then isSymlink(); if all three return false it throws this IllegalArgumentException. Hadoop's own FileStatus always satisfies one of them, so in practice this fires for custom or mocked FileStatus implementations behind HttpFS (e.g. third-party FileSystem adapters or test doubles) that leave the object in an inconsistent type state.","triggerScenarios":"An HttpFS server backed by a custom FileSystem whose FileStatus sets neither the file nor directory flag (e.g. constructed via a bare new FileStatus() with nothing set and isSymlink() overridden to false); unit/integration tests feeding hand-built FileStatus objects into code that serializes them via FILE_TYPE.getType; FilterFileSystem shims that forward to a partially implemented backing store.","commonSituations":"Writing a custom FileSystem to expose a store through HttpFS and forgetting to mark statuses as file or directory; mock-based tests where Mockito returns default false for all three probes; upgrades where a third-party connector lags the FileStatus API (e.g. symlink support stubs returning false).","solutions":["Fix the FileStatus producer: construct it with an explicit type, e.g. new FileStatus(len, isDir, repl, bs, mtime, atime, permission, owner, group, path) with isDir set correctly, or call setIsDir/setSymlink on mutable implementations.","In tests, build FileStatus with real constructors instead of default Mockito mocks, or stub isFile()/isDirectory() to return true for one.","If the status is legitimately unknown, resolve it before serialization rather than passing a neutral FileStatus down."],"exampleFix":"// before\nFileStatus st = mock(FileStatus.class);          // all probes false -> 3618\n// after\nFileStatus st = new FileStatus(1024, false, 1, 128L<<20,\n    System.currentTimeMillis(), System.currentTimeMillis(),\n    FsPermission.getDefault(), \"owner\", \"group\", new Path(\"/f\"));\n// (isDir=false => isFile() true)","handlingStrategy":"type-guard","validationCode":"import org.apache.hadoop.fs.FileStatus;\nstatic String fileTypeOf(FileStatus st) {\n  if (st.isFile()) return \"FILE\";\n  if (st.isDirectory()) return \"DIRECTORY\";\n  if (st.isSymlink()) return \"SYMLINK\";\n  throw new IllegalStateException(\"FileStatus has no type: \" + st.getPath());\n}","typeGuard":"static boolean hasKnownFileType(FileStatus st) {\n  return st.isFile() || st.isDirectory() || st.isSymlink();\n}","tryCatchPattern":"try {\n  return FILE_TYPE.getType(status).toString();\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Could not determine filetype\")) {\n    log.error(\"backing FileSystem returned typeless FileStatus for {}\", status.getPath());\n  }\n  throw e;\n}","preventionTips":["When implementing a FileSystem, always build FileStatus with an explicit isDir/symlink flag.","In tests, construct FileStatus with real constructors; stub at least one type probe on mocks.","Guard serialization of third-party statuses with hasKnownFileType and log the path."],"tags":["httpfs","filestatus","json-serialization","custom-filesystem","testing"],"backgroundTag":"unknown-file-type","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}