MuntashirAkon/AppManager · error · IOException
already exists.
Error message
already exists.
What it means
createDirectories() checks whether the final segment already exists (via the VFS root or findFile) and throws IOException("<uri> already exists.") if it does. The method only creates directories; it does not tolerate existing entries, unlike a true mkdirs/exists-ok semantic. The message includes the existing entry's URI.
Solutions
- Check hasFile(lastSegment) or catch the IOException and treat "already exists" as success if an existing directory is acceptable.
- Use findOrCreateDirectory instead of createDirectories when existence is expected.
- Delete or rename the conflicting existing entry before creating.
- Guard concurrent creators with app-level synchronization or a unique per-run name.
Example fix
// before
path.createDirectories("logs"); // throws on second run
// after
if (!path.hasFile("logs")) {
path.createDirectories("logs");
} else {
path.findOrCreateDirectory("logs");
} Defensive patterns
Strategy: try-catch
Validate before calling
boolean exists = path.hasFile(lastSegment);
if (exists) { /* reuse, rename, or delete first */ } Try / catch
try {
return path.createDirectories(name);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().endsWith(" already exists.")) {
return path.findOrCreateDirectory(name); // tolerate existing
}
throw e;
} Prevention
- Make creation idempotent via hasFile checks
- Use unique per-run directory names for concurrent writers
- Clean up stale entries from previous runs
When it happens
Trigger: Calling createDirectories when the last path segment already exists as any entry (file or directory) at that location, e.g. a second call with the same name, or a file already occupying the name.
Common situations: Re-running an install/setup routine that creates fixed directories; a race where another process created the directory first; a stale file with the intended directory name left from a previous version.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Directory cannot be converted to file
- Mount point ( ) is already in use.
- Cannot find
- Class definition for + node.getFullPath() + is not found.
- Class definition for + src.getFullPath() + is not found.
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/01aaf7fe3ddaed57.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/io/github/muntashirakon/io/PathImpl.java:449
if (displayName == null) {
throw new IOException("Empty display name.");
}
String[] dirNames = displayName.split(File.separator);
if (dirNames.length == 0) {
throw new IllegalArgumentException("Display name is empty");
}
for (String name : dirNames) {
if (name.equals("..")) {
throw new IOException("Could not create directories in the parent directory.");
}
}
DocumentFile file = createArbitraryDirectories(documentFile, dirNames, dirNames.length - 1);
// Special case for the last segment
String lastSegment = dirNames[dirNames.length - 1];
Path fsRoot = VirtualFileSystem.getFsRoot(Paths.appendPathSegment(file.getUri(), lastSegment));
DocumentFile t = fsRoot != null ? fsRoot.documentFile : file.findFile(lastSegment);
if (t != null) {
throw new IOException(t.getUri() + " already exists.");
}
t = file.createDirectory(lastSegment);
if (t == null) {
throw new IOException("Directory" + file.getUri() + File.separator + lastSegment + " could not be created.");
}
return new PathImpl(context, t);
}
@Nullable
public Path getParent() {
DocumentFile file = getRealDocumentFile(documentFile).getParentFile();
return file == null ? null : new PathImpl(context, file);
}
public boolean hasFile(@NonNull String displayName) {
return findFileInternal(documentFile, displayName) != null;
}
View on GitHub (pinned to 0152f468fc)