MuntashirAkon/AppManager · error · IOException

exists and it is not a directory.

Error message

 exists and it is not a directory.

What it means

Thrown by PathImpl's mkdirs helper when an intermediate path segment already exists but is a regular file rather than a directory. While creating the directory chain, the library finds an existing document with the segment's name whose isDirectory() is false and aborts rather than overwrite.

Solutions

  1. Inspect the existing document at the colliding segment and rename/delete it if appropriate
  2. Use a different base directory for the new tree
  3. Check each segment with findFile() + isDirectory() before creating to give a precise error

Example fix

// before
dir.createDirectories("logs/session/x");
// after
Path p = dir;
for (String seg : new String[]{"logs", "session", "x"}) {
    Path child = p.findFile(seg);
    if (child != null && !child.isDirectory()) {
        throw new FileAlreadyExistsException("File blocks directory creation: " + child);
    }
    p = (child != null) ? child : p.createDirectory(seg);
}
Defensive patterns

Strategy: validation

Validate before calling

for (String seg : segments) { Path c = base.findFile(seg); if (c != null && !c.isDirectory()) throw new FileAlreadyExistsException(seg); }

Type guard

null

Try / catch

try { dir.createDirectories(chain); } catch (IOException e) { logCollision(chain); throw e; }

Prevention

When it happens

Trigger: Calling Path.createDirectories()/createDirectoryAndParents-style APIs where a component of the path (e.g. 'a/b/c' with 'a/b' being an existing file) collides with an existing non-directory document.

Common situations: Path layout changed between app versions (old file now sits where a folder is expected); data restored from backup creating files where directories should be; typos causing name collisions with existing files.

Related errors


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

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/io/PathImpl.java:1347

            return null;
        }
        // FIXME: 9/9/23 This doesn't actually work for content URIs
        Uri parentUri = Paths.removeLastPathSegment(mountPoint);
        return new PathImpl(context, parentUri).documentFile;
    }

    @NonNull
    private static DocumentFile createArbitraryDirectories(@NonNull DocumentFile documentFile,
                                                           @NonNull String[] names,
                                                           int length) throws IOException {
        DocumentFile file = getRealDocumentFile(documentFile);
        for (int i = 0; i < length; ++i) {
            Path fsRoot = VirtualFileSystem.getFsRoot(Paths.appendPathSegment(file.getUri(), names[i]));
            DocumentFile t = fsRoot != null ? fsRoot.documentFile : file.findFile(names[i]);
            if (t == null) {
                t = file.createDirectory(names[i]);
            } else if (!t.isDirectory()) {
                throw new IOException(t.getUri() + " exists and it is not a directory.");
            }
            if (t == null) {
                throw new IOException("Could not create directory " + file.getUri() + File.separatorChar + names[i]);
            }
            file = t;
        }
        return file;
    }

    @NonNull
    private static DocumentFile getRealDocumentFile(@NonNull DocumentFile documentFile) {
        Path fsRoot = VirtualFileSystem.getFsRoot(documentFile.getUri());
        if (fsRoot != null) {
            return fsRoot.documentFile;
        }
        return documentFile;
    }

View on GitHub (pinned to 0152f468fc)