{"record":{"id":"e392a97e4fe720d4","repo":"skylot/jadx","slug":"can-t-create-directory-dir","errorCode":null,"errorMessage":"Can't create directory ${dir}","messagePattern":"Can't create directory (.+?)","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java","lineNumber":148,"sourceCode":"\tpublic static void makeDirsForFile(Path path) {\n\t\tif (path != null) {\n\t\t\tmakeDirs(path.toAbsolutePath().getParent().toFile());\n\t\t}\n\t}\n\n\tpublic static void makeDirsForFile(File file) {\n\t\tif (file != null) {\n\t\t\tmakeDirs(file.getParentFile());\n\t\t}\n\t}\n\n\tprivate static final Object MKDIR_SYNC = new Object();\n\n\tpublic static void makeDirs(@Nullable File dir) {\n\t\tif (dir != null) {\n\t\t\tsynchronized (MKDIR_SYNC) {\n\t\t\t\tif (!dir.mkdirs() && !dir.isDirectory()) {\n\t\t\t\t\tthrow new JadxRuntimeException(\"Can't create directory \" + dir);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic static void makeDirs(@Nullable Path dir) {\n\t\tif (dir != null) {\n\t\t\tmakeDirs(dir.toFile());\n\t\t}\n\t}\n\n\tpublic static void deleteFileIfExists(Path filePath) throws IOException {\n\t\tFiles.deleteIfExists(filePath);\n\t}\n\n\tpublic static boolean deleteDir(File dir) {\n\t\tdeleteDir(dir.toPath());\n\t\treturn true;","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java#L130-L166","documentation":"Thrown by makeDirs(File) when dir.mkdirs() returns false AND dir.isDirectory() returns false. This means the directory could not be created and does not already exist as a directory. The mkdirs() call fails silently (returns false) on permission denial, a parent path component that is a regular file, or a read-only filesystem. The double-check (!isDirectory) allows the call to succeed if the directory already existed (mkdirs returns false but isDirectory returns true).","triggerScenarios":"Calling makeDirs on a path whose parent component is a regular file (e.g., '/foo/bar' where 'foo' is a file), on a read-only filesystem, where the process lacks write permission on the parent, or where the path name contains illegal characters for the OS. Also when disk/inode exhaustion prevents directory creation.","commonSituations":"Output directory path collides with an existing file name. Running on a read-only root filesystem in a container. Insufficient permissions on the target directory's parent. Windows path with reserved characters. SELinux denying the operation.","solutions":["Check whether a parent component is a file: verify each ancestor with Files.isDirectory.","Verify write permission on the parent: Files.isWritable(dir.getParentFile().toPath()).","Remove or rename a colliding file that occupies the intended directory path.","Check filesystem mount options (read-only) and disk/inode availability."],"exampleFix":"// before\nFileUtils.makeDirs(outputDir);\n\n// after\nPath parent = outputDir.toPath().getParent();\nif (parent != null && Files.exists(parent) && !Files.isDirectory(parent)) {\n    throw new IllegalStateException(parent + \" is a file, cannot create dir under it\");\n}\nFileUtils.makeDirs(outputDir);","handlingStrategy":"validation","validationCode":"public static void validateMkdirTarget(File dir) throws IOException {\n    File parent = dir.getParentFile();\n    while (parent != null) {\n        if (parent.exists() && !parent.isDirectory()) {\n            throw new IOException(\"ancestor is a file, not a directory: \" + parent);\n        }\n        parent = parent.getParentFile();\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    FileUtils.makeDirs(dir);\n} catch (JadxRuntimeException e) {\n    // no wrapped cause — check the directory state directly\n    if (dir.isDirectory()) return; // benign: already exists\n    throw e;\n}","preventionTips":["Check no ancestor path component is a regular file before creating directories.","Verify write permission on the deepest existing ancestor.","Check filesystem mount options for read-only."],"tags":["filesystem","mkdir","permissions","jadx"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}