{"record":{"id":"38af081d7ae97018","repo":"alibaba/arthas","slug":"file-file-exists-but-is-a-directory","errorCode":null,"errorMessage":"File '{file}' exists but is a directory","messagePattern":"File '(.+?)' exists but is a directory","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"common/src/main/java/com/taobao/arthas/common/FileUtils.java","lineNumber":116,"sourceCode":"\t * The parent directory will be created if it does not exist. The file will be\n\t * created if it does not exist. An exception is thrown if the file object\n\t * exists but is a directory. An exception is thrown if the file exists but\n\t * cannot be written to. An exception is thrown if the parent directory cannot\n\t * be created.\n\t *\n\t * @param file   the file to open for output, must not be {@code null}\n\t * @param append if {@code true}, then bytes will be added to the end of the\n\t *               file rather than overwriting\n\t * @return a new {@link FileOutputStream} for the specified file\n\t * @throws IOException if the file object is a directory\n\t * @throws IOException if the file cannot be written to\n\t * @throws IOException if a parent directory needs creating but that fails\n\t * @since 2.1\n\t */\n\tpublic static FileOutputStream openOutputStream(final File file, final boolean append) throws IOException {\n\t\tif (file.exists()) {\n\t\t\tif (file.isDirectory()) {\n\t\t\t\tthrow new IOException(\"File '\" + file + \"' exists but is a directory\");\n\t\t\t}\n\t\t\tif (!file.canWrite()) {\n\t\t\t\tthrow new IOException(\"File '\" + file + \"' cannot be written to\");\n\t\t\t}\n\t\t} else {\n\t\t\tfinal File parent = file.getParentFile();\n\t\t\tif (parent != null) {\n\t\t\t\tif (!parent.mkdirs() && !parent.isDirectory()) {\n\t\t\t\t\tthrow new IOException(\"Directory '\" + parent + \"' could not be created\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn new FileOutputStream(file, append);\n\t}\n\t\n    /**\n     * Reads the contents of a file into a byte array.\n     * The file is always closed.","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/common/src/main/java/com/taobao/arthas/common/FileUtils.java#L98-L134","documentation":"FileUtils.openOutputStream(file, append) checks the existing target: if file.exists() && file.isDirectory(), it throws IOException(\"File '<file>' exists but is a directory\"). You cannot open a FileOutputStream on a directory entry.","triggerScenarios":"Passing a File path that resolves to an existing directory (e.g. output path equals a folder, or a missing filename so the path collapses to a directory).","commonSituations":"Output path config omitting the filename (path ends at a directory); a path collision where a log/output dir shares a name with the intended file; user supplied a directory where a file path was expected.","solutions":["Append a filename to the path so it targets a file, not a directory.","Validate file.isFile() (or !isDirectory()) before calling openOutputStream.","If writing many files, loop over names inside the directory rather than writing to the directory itself."],"exampleFix":"// before\nFileUtils.openOutputStream(new File(\"/var/log/arthas\"), false);  // /var/log/arthas is a dir -> throws\n\n// after\nFileUtils.openOutputStream(new File(\"/var/log/arthas\", \"trace.log\"), false);","handlingStrategy":"validation","validationCode":"if (file.exists() && file.isDirectory()) {\n    throw new IOException(\"target is a directory: \" + file);\n}","typeGuard":"static boolean isWritableFile(File f) {\n    return f != null && (!f.exists() || f.isFile());\n}","tryCatchPattern":"try {\n    return FileUtils.openOutputStream(file, append);\n} catch (IOException e) {\n    if (e.getMessage().endsWith(\"is a directory\")) {\n        // append a filename or pick a different path\n    } else throw e;\n}","preventionTips":["Always include a filename in output paths.","Validate !file.isDirectory() before opening for output.","Distinguish directory vs file paths in configuration schemas."],"tags":["filesystem","io","validation","common"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}