{"record":{"id":"dcaa49056c8caa58","repo":"MuntashirAkon/AppManager","slug":"could-not-create-directory-datasourcefile","errorCode":null,"errorMessage":"Could not create directory ${dataSourceFile}","messagePattern":"Could not create directory (.+?)","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java","lineNumber":570,"sourceCode":"                case BackupDataDirectoryInfo.TYPE_DEVICE_PROTECTED:\n                    // NOP\n                    break;\n            }\n        } else {\n            // Skip if internal data restore is not requested.\n            if (!mRequestedFlags.backupInternalData()) {\n                return;\n            }\n        }\n        // Create data folder if not exists\n        if (!dataSourceFile.exists()) {\n            if (dataDirectoryInfo.isExternal() && !dataDirectoryInfo.isMounted) {\n                if (!Utils.isRoboUnitTest()) {\n                    throw new BackupException(\"External directory containing \" + dataSource + \" is not mounted.\");\n                } // else Skip checking for mounted partition for robolectric tests\n            }\n            if (!dataSourceFile.mkdirs()) {\n                throw new BackupException(\"Could not create directory \" + dataSourceFile);\n            }\n            if (!dataDirectoryInfo.isExternal()) {\n                // Restore UID, GID\n                dataSourceFile.setUidGid(uidGidPair);\n            }\n        }\n        // Decrypt data\n        try {\n            dataFiles = mBackupItem.decrypt(dataFiles);\n        } catch (IOException e) {\n            throw new BackupException(\"Failed to decrypt \" + Arrays.toString(dataFiles), e);\n        }\n        // Extract data to the data directory\n        try {\n            String publicSourceDir = new File(Objects.requireNonNull(mPackageInfo.applicationInfo).publicSourceDir).getParent();\n            TarUtils.extract(mBackupInfo.tarType, dataFiles, dataSourceFile, null, BackupUtils\n                    .getExcludeDirs(!mRequestedFlags.backupCache(), null), publicSourceDir);\n        } catch (Throwable th) {","sourceCodeStart":552,"sourceCodeEnd":588,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java#L552-L588","documentation":"restoreDirectory calls File.mkdirs() on the target data directory when it doesn't exist; if mkdirs() returns false (directory could not be created), this BackupException is thrown. Typical causes are permission problems on the parent path or a leftover non-directory file occupying the path.","triggerScenarios":"mkdirs() fails because the parent directory is not writable (missing root on /data/data/<pkg>); a regular file already exists at the target path; SELinux denies creation; storage is full or read-only mount.","commonSituations":"Restoring without root to another app's private data dir; a stale file left by a previous failed restore; read-only filesystem after a crash; disk full on device.","solutions":["Ensure the restore runs with root privileges so private app directories can be created.","Delete any stale file or broken symlink at the target path, then retry.","Free up storage space and confirm the target filesystem is mounted read-write.","Restore ownership/permissions on the parent directory (chown to the app's uid, as the code does with uidGidPair)."],"exampleFix":"// before: mkdirs failing on stale path\n// (inside restoreDirectory)\nif (!dataSourceFile.mkdirs()) { throw new BackupException(...); }\n// after: clean path first\nif (dataSourceFile.exists() && !dataSourceFile.isDirectory()) {\n    Paths.delete(dataSourceFile); // remove stale file/symlink\n}\nif (!dataSourceFile.mkdirs()) { throw new BackupException(...); }","handlingStrategy":"try-catch","validationCode":"File target = new File(dataSource);\nif (target.exists() && !target.isDirectory())\n    throw new IllegalStateException(\"Stale file blocks directory creation: \" + target);\nif (target.getParentFile() != null && !target.getParentFile().canWrite())\n    throw new IllegalStateException(\"Parent not writable (root needed?): \" + target.getParent());\n","typeGuard":"boolean canCreateDir(File f) { return !f.exists() || f.isDirectory(); }","tryCatchPattern":"try { runRestore(); } catch (BackupException e) {\n    if (e.getMessage().startsWith(\"Could not create directory\")) {\n        // parse path from message, clean stale file, ensure root, retry once\n        cleanAndRetry(e.getMessage());\n    } else throw e;\n}","preventionTips":["Run restores with root when touching other apps' private dirs.","Clean up after failed restores to remove stale files/symlinks.","Ensure sufficient free space and a read-write filesystem.","Check SELinux denials in logcat if mkdirs keeps failing."],"tags":["android","backup","mkdir","permissions","filesystem"],"backgroundTag":"mkdir-permission-denied","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"}