MuntashirAkon/AppManager · error · IOException

Could not create directories in the parent directory.

Error message

Could not create directories in the parent directory.

What it means

createNewArbitraryFile splits the display name on File.separator and creates any intermediate directories before the final file. Because SAF tree URIs cannot address above their tree root, a ".." segment would attempt to escape the parent; the library blocks this outright with this IOException.

Source

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

        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) {
            if (name.equals("..")) {
                throw new IOException("Could not create directories in the parent directory.");
            }
        }
        DocumentFile file = createArbitraryDirectories(documentFile, names, names.length - 1);
        return createFileAsDirectChild(context, file, names[names.length - 1], mimeType);
    }

    @NonNull
    public Path createDirectoriesIfRequired(@NonNull String displayName) throws IOException {
        displayName = Paths.sanitize(displayName, true);
        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("..")) {

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Normalize the input path and reject or strip any ".." segments before calling
  2. Resolve the intended location yourself and pass only a name relative to the current Path
  3. If the user genuinely needs a location outside this tree, create a Path for that tree instead

Example fix

// before
path.createNewArbitraryFile("../escape.txt", mime);
// after
if (Arrays.asList(name.split("/")).contains("..")) {
    throw new IllegalArgumentException("Parent-directory segments not allowed");
}
path.createNewArbitraryFile(name, mime);
Defensive patterns

Strategy: validation

Validate before calling

for (String seg : displayName.split("/")) { if ("..".equals(seg)) { throw new IllegalArgumentException(".. not allowed"); } }

Prevention

When it happens

Trigger: Passing a display name containing a ".." path segment (e.g. "../escape.txt", "a/../../b.txt") to createNewArbitraryFile.

Common situations: Building filenames from remote/relative paths that include parent-directory references; processing untrusted input that contains traversal sequences; converting Unix-style relative paths into SAF names.

Understand the failure class

Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.

Related errors


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