{"record":{"id":"231aa95bd14dc2f7","repo":"asLody/VirtualApp","slug":"couldn-t-create-directory","errorCode":null,"errorMessage":"Couldn't create directory ","messagePattern":"Couldn't create directory ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"VirtualApp/lib/src/main/java/com/lody/virtual/helper/utils/AtomicFile.java","lineNumber":88,"sourceCode":"    public FileOutputStream startWrite() throws IOException {\n        // Rename the current file so it may be used as a backup during the next read\n        if (mBaseName.exists()) {\n            if (!mBackupName.exists()) {\n                if (!mBaseName.renameTo(mBackupName)) {\n                    Log.w(\"AtomicFile\", \"Couldn't rename file \" + mBaseName\n                            + \" to backup file \" + mBackupName);\n                }\n            } else {\n                mBaseName.delete();\n            }\n        }\n        FileOutputStream str = null;\n        try {\n            str = new FileOutputStream(mBaseName);\n        } catch (FileNotFoundException e) {\n            File parent = mBaseName.getParentFile();\n            if (!parent.mkdir()) {\n                throw new IOException(\"Couldn't create directory \" + mBaseName);\n            }\n            try {\n                str = new FileOutputStream(mBaseName);\n            } catch (FileNotFoundException e2) {\n                throw new IOException(\"Couldn't create \" + mBaseName);\n            }\n        }\n        return str;\n    }\n\n    /**\n     * Call when you have successfully finished writing to the stream\n     * returned by {@link #startWrite()}.  This will close, sync, and\n     * commit the new data.  The next attempt to read the atomic file\n     * will return the new file stream.\n     */\n    public void finishWrite(FileOutputStream str) {\n        if (str != null) {","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/asLody/VirtualApp/blob/666fefcb5d3f39cc944001c3457c38ffd6544c87/VirtualApp/lib/src/main/java/com/lody/virtual/helper/utils/AtomicFile.java#L70-L106","documentation":"AtomicFile.startWrite opens the base file for writing; on FileNotFoundException it attempts parent.mkdir() to recreate a missing directory. If that mkdir fails it throws this IOException including the file path. It protects atomic-write users from silently writing into a nonexistent directory.","triggerScenarios":"Calling AtomicFile.startWrite (directly or via writeUserLocked/writeUserListLocked) when the base file's parent directory does not exist and mkdir() returns false (permission denied, parent-of-parent missing, or storage unmounted).","commonSituations":"External storage unmounted or read-only; data directory wiped while service still holds an AtomicFile; wrong base path constructed for a restricted user; Android scoped-storage restrictions.","solutions":["Ensure the parent directory exists before creating AtomicFile, using mkdirs() on the full chain and checking writable state","Verify storage is mounted (Environment.getExternalStorageState) and path is app-writable","Log/inspect the exact path; fix the path construction to live under context.getFilesDir()/getCacheDir()"],"exampleFix":"// before\nAtomicFile af = new AtomicFile(new File(\"/data/system/users/0/x.xml\"));\n// after\nFile dir = new File(\"/data/system/users/0\");\nif (!dir.exists() && !dir.mkdirs()) {\n    throw new IOException(\"cannot create \" + dir);\n}\nAtomicFile af = new AtomicFile(new File(dir, \"x.xml\"));","handlingStrategy":"validation","validationCode":"File base = new File(dir, \"file.xml\");\nFile parent = base.getParentFile();\nif (!parent.isDirectory() && !parent.mkdirs()) {\n    throw new IOException(\"cannot create \" + parent);\n}\nif (!parent.canWrite()) throw new IOException(\"not writable: \" + parent);","typeGuard":null,"tryCatchPattern":"try {\n    FileOutputStream out = atomicFile.startWrite();\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Couldn't create directory\")) {\n        // recreate directory chain or switch to a writable location\n    }\n}","preventionTips":["Create parent directories with mkdirs() before constructing AtomicFile","Verify storage mounted and writable (Environment.getExternalStorageState)","Base file paths under context.getFilesDir()/getCacheDir()"],"tags":["android","io","directory","atomic-file"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"666fefcb5d3f39cc944001c3457c38ffd6544c87","analyzedAt":"2026-09-09T11:09:01.694Z","contentChangedAt":"2026-09-09T11:09:01.694Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}