{"record":{"id":"ea508350be5e7218","repo":"MuntashirAkon/AppManager","slug":"could-not-create-directory-named-displayname","errorCode":null,"errorMessage":"Could not create directory named ${displayName}","messagePattern":"Could not create directory named (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/io/PathImpl.java","lineNumber":386,"sourceCode":"        return createFileAsDirectChild(context, documentFile, displayName, mimeType);\n    }\n\n    @NonNull\n    public Path createNewDirectory(@NonNull String displayName) throws IOException {\n        displayName = Paths.sanitize(displayName, true);\n        if (displayName == null) {\n            throw new IOException(\"Empty display name.\");\n        }\n        if (displayName.indexOf(File.separatorChar) != -1) {\n            throw new IllegalArgumentException(\"Display name contains file separator.\");\n        }\n        DocumentFile documentFile = getRealDocumentFile(this.documentFile);\n        if (!documentFile.isDirectory()) {\n            throw new IOException(\"Current file is not a directory.\");\n        }\n        checkVfs(Paths.appendPathSegment(documentFile.getUri(), displayName));\n        DocumentFile file = documentFile.createDirectory(displayName);\n        if (file == null) throw new IOException(\"Could not create directory named \" + displayName);\n        return new PathImpl(context, file);\n    }\n\n    @NonNull\n    public Path createNewArbitraryFile(@NonNull String displayName, @Nullable String mimeType) throws IOException {\n        displayName = Paths.sanitize(displayName, true);\n        if (displayName == null) {\n            throw new IOException(\"Empty display name.\");\n        }\n        String[] names = displayName.split(File.separator);\n        if (names.length == 0) {\n            throw new IllegalArgumentException(\"Display name is empty.\");\n        }\n        for (String name : names) {\n            if (name.equals(\"..\")) {\n                throw new IOException(\"Could not create directories in the parent directory.\");\n            }\n        }","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/io/PathImpl.java#L368-L404","documentation":"After passing the is-directory check, createNewDirectory delegates to DocumentFile.createDirectory(displayName). SAF returns null when the underlying DocumentsProvider refuses or fails to create the folder, and the library converts that null into this IOException. The provider's reason (permission, existing name, storage full) is not surfaced.","triggerScenarios":"Calling createNewDirectory when the provider cannot create the folder: read-only tree URI (e.g. USB OTG without write permission), provider crash, name colliding in an unexpected way, or external storage unavailable.","commonSituations":"Working with external SD-card trees on Android without SAF write grants; cloud DocumentsProviders being offline; storage full; creating directories inside a tree obtained with a read-only intent.","solutions":["Verify the app can write to the tree (try creating a throwaway file first, or check canWrite() on the DocumentFile)","Re-request the tree URI with Intent.FLAG_GRANT_READ/WRITE and ACTION_OPEN_DOCUMENT_TREE for a writable grant","Check device storage/free space and that the external volume is mounted","Catch the IOException and show a user-facing 'could not create folder' message with the target name"],"exampleFix":"// before\nparent.createNewDirectory(name); // may fail silently in provider\n// after\nif (!parent.toDocumentFile().canWrite()) {\n    requestWritableTreeAccess(); // re-launch ACTION_OPEN_DOCUMENT_TREE\n}\nparent.createNewDirectory(name);","handlingStrategy":"try-catch","validationCode":"if (!parentDoc.canWrite()) { requestWritableTreeAccess(); }","typeGuard":null,"tryCatchPattern":"try {\n    Path dir = parent.createNewDirectory(name);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Could not create directory named\")) {\n        showCreateFailed(context, name); // provider refused; check grants/storage\n    } else throw e;\n}","preventionTips":["Request the tree URI with both read and write grants and persist them","Test write access (canWrite()) before batch folder creation","Check storage free space and volume mount state on external/SD storage","Don't rely on read-only tree URIs (e.g. downloads provider) for creation"],"tags":["android","saf","directory-creation","permissions"],"backgroundTag":"file-write-failed","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}