{"record":{"id":"acbe3b6c13a45699","repo":"MuntashirAkon/AppManager","slug":"current-file-is-not-a-directory","errorCode":null,"errorMessage":"Current file is not a directory.","messagePattern":"Current file is not a directory\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/io/PathImpl.java","lineNumber":382,"sourceCode":"        displayName = Paths.sanitize(displayName, true);\n        if (displayName == null) {\n            throw new IOException(\"Empty display name.\");\n        }\n        return createFileAsDirectChild(context, documentFile, displayName, mimeType);\n    }\n\n    @NonNull\n    public Path createNewDirectory(@NonNull String displayName) throws IOException {\n        displayName = Paths.sanitize(displayName, true);\n        if (displayName == null) {\n            throw new IOException(\"Empty display name.\");\n        }\n        if (displayName.indexOf(File.separatorChar) != -1) {\n            throw new IllegalArgumentException(\"Display name contains file separator.\");\n        }\n        DocumentFile documentFile = getRealDocumentFile(this.documentFile);\n        if (!documentFile.isDirectory()) {\n            throw new IOException(\"Current file is not a directory.\");\n        }\n        checkVfs(Paths.appendPathSegment(documentFile.getUri(), displayName));\n        DocumentFile file = documentFile.createDirectory(displayName);\n        if (file == null) throw new IOException(\"Could not create directory named \" + displayName);\n        return new PathImpl(context, file);\n    }\n\n    @NonNull\n    public Path createNewArbitraryFile(@NonNull String displayName, @Nullable String mimeType) throws IOException {\n        displayName = Paths.sanitize(displayName, true);\n        if (displayName == null) {\n            throw new IOException(\"Empty display name.\");\n        }\n        String[] names = displayName.split(File.separator);\n        if (names.length == 0) {\n            throw new IllegalArgumentException(\"Display name is empty.\");\n        }\n        for (String name : names) {","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/io/PathImpl.java#L364-L400","documentation":"createNewDirectory creates the new folder as a direct child of the current Path. Before delegating to DocumentFile.createDirectory, it verifies the underlying DocumentFile is a directory; if the current path points to a regular file (or its type cannot be a directory), this IOException is thrown.","triggerScenarios":"Calling createNewDirectory on a Path that wraps a file (e.g. obtained via a full path to a document, or after the target was replaced by a file with the same name), or on a non-existent/non-directory tree URI.","commonSituations":"Keeping a cached Path that later got replaced; iterating a heterogeneous list of files/folders and creating subfolders without checking isDirectory(); SAF URI resolving to a document rather than a tree.","solutions":["Check path.isDirectory() (or DocumentFile.isDirectory) before calling createNewDirectory","If the path is a file, navigate to its parent (path.getParent()) and create the directory there","Re-resolve the Path from the intended tree URI if the cached handle is stale"],"exampleFix":"// before\nfolder.createNewDirectory(\"sub\");\n// after\nPath target = folder.isDirectory() ? folder : folder.getParent();\ntarget.createNewDirectory(\"sub\");","handlingStrategy":"validation","validationCode":"if (!path.isDirectory()) { path = path.getParent(); } // or abort","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always check isDirectory() before child-creation APIs","Re-resolve cached Paths instead of reusing handles across long sessions","Don't assume a URI points to a directory — SAF documents can be files"],"tags":["android","saf","directory-creation"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}