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

  1. Check path.isDirectory() (or DocumentFile.isDirectory) before calling createNewDirectory
  2. If the path is a file, navigate to its parent (path.getParent()) and create the directory there
  3. 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

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


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/acbe3b6c13a45699. Report an issue: GitHub.