MuntashirAkon/AppManager · error · IOException
Current file is not a directory.
Error message
Current file is not a directory.
What it means
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.
Source
Thrown at app/src/main/java/io/github/muntashirakon/io/PathImpl.java:382
displayName = Paths.sanitize(displayName, true);
if (displayName == null) {
throw new IOException("Empty display name.");
}
return createFileAsDirectChild(context, documentFile, displayName, mimeType);
}
@NonNull
public Path createNewDirectory(@NonNull String displayName) throws IOException {
displayName = Paths.sanitize(displayName, true);
if (displayName == null) {
throw new IOException("Empty display name.");
}
if (displayName.indexOf(File.separatorChar) != -1) {
throw new IllegalArgumentException("Display name contains file separator.");
}
DocumentFile documentFile = getRealDocumentFile(this.documentFile);
if (!documentFile.isDirectory()) {
throw new IOException("Current file is not a directory.");
}
checkVfs(Paths.appendPathSegment(documentFile.getUri(), displayName));
DocumentFile file = documentFile.createDirectory(displayName);
if (file == null) throw new IOException("Could not create directory named " + displayName);
return new PathImpl(context, file);
}
@NonNull
public Path createNewArbitraryFile(@NonNull String displayName, @Nullable String mimeType) throws IOException {
displayName = Paths.sanitize(displayName, true);
if (displayName == null) {
throw new IOException("Empty display name.");
}
String[] names = displayName.split(File.separator);
if (names.length == 0) {
throw new IllegalArgumentException("Display name is empty.");
}
for (String name : names) {View on GitHub (pinned to 0152f468fc)
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
Example fix
// before
folder.createNewDirectory("sub");
// after
Path target = folder.isDirectory() ? folder : folder.getParent();
target.createNewDirectory("sub"); Defensive patterns
Strategy: validation
Validate before calling
if (!path.isDirectory()) { path = path.getParent(); } // or abort Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Could not create directory named ${displayName}
- Directory
- Unable to open output stream.
- Could not fetch attributes for tree ${documentUri}
- Could not create
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/acbe3b6c13a45699.
Report an issue: GitHub.