{"record":{"id":"3e16a9fca611a357","repo":"CarGuo/GSYVideoPlayer","slug":"directory-s-can-t-be-created","errorCode":null,"errorMessage":"Directory %s can't be created","messagePattern":"Directory (.+?) can't be created","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"gsyVideoPlayer-proxy_cache/src/main/java/com/danikula/videocache/file/Files.java","lineNumber":31,"sourceCode":"import java.util.List;\n\n/**\n * Utils for work with files.\n *\n * @author Alexey Danilov (danikula@gmail.com).\n */\nclass Files {\n\n\n    static void makeDir(File directory) throws IOException {\n        if (directory.exists()) {\n            if (!directory.isDirectory()) {\n                throw new IOException(\"File \" + directory + \" is not directory!\");\n            }\n        } else {\n            boolean isCreated = directory.mkdirs();\n            if (!isCreated) {\n                throw new IOException(String.format(\"Directory %s can't be created\", directory.getAbsolutePath()));\n            }\n        }\n    }\n\n    static List<File> getLruListFiles(File directory) {\n        List<File> result = new LinkedList<>();\n        File[] files = directory.listFiles();\n        if (files != null) {\n            result = Arrays.asList(files);\n            Collections.sort(result, new LastModifiedComparator());\n        }\n        return result;\n    }\n\n    static void setLastModifiedNow(File file) throws IOException {\n        if (file.exists()) {\n            long now = System.currentTimeMillis();\n            boolean modified = file.setLastModified(now); // on some devices (e.g. Nexus 5) doesn't work","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/CarGuo/GSYVideoPlayer/blob/e5d74d3aa9d7fb1393a879e33ee380f8f41354f1/gsyVideoPlayer-proxy_cache/src/main/java/com/danikula/videocache/file/Files.java#L13-L49","documentation":"Files.makeDir's second failure mode: when the directory does not exist and mkdirs() returns false (or a concurrent delete raced the check), it throws IOException('Directory <path> can't be created'). Called from FileCache's constructor, it surfaces as ProxyCacheException when the proxy cannot create the cache directory it was configured with.","triggerScenarios":"new FileCache(...) -> Files.makeDir(parent) where the cache directory is missing and mkdirs() fails: missing write permission on the parent (scoped storage, unmounted external volume), a parent path component existing as a file, or disk/filesystem errors.","commonSituations":"Scoped storage restrictions, missing legacy storage flag (requestLegacyExternalStorage) on Android 10, unmounted removable storage, read-only fs.","solutions":["Use app-scoped cache dirs (getCacheDir/getExternalCacheDir)","Add android:requestLegacyExternalStorage=\"true\" in the manifest for Android 10 targets still using shared paths","Verify storage mount state and permissions before constructing the proxy","Fall back to internal cache dir when external is unavailable"],"exampleFix":"// before\nFile dir = new File(\"/sdcard/videocache\");\n\n// after\nFile dir = ctx.getExternalCacheDir() != null\n        ? new File(ctx.getExternalCacheDir(), \"videocache\")\n        : new File(ctx.getCacheDir(), \"videocache\");","handlingStrategy":"validation","validationCode":"File dir = new File(context.getCacheDir(), \"proxy\");\nif (!dir.exists()) {\n    boolean ok = dir.mkdirs();\n    if (!ok && !dir.isDirectory()) {\n        dir = context.getCacheDir(); // guaranteed writable fallback\n    }\n}","typeGuard":null,"tryCatchPattern":"catch (IOException e) {\n    if (String.valueOf(e.getMessage()).contains(\"can't be created\")) {\n        // fall back to internal cache dir and retry construction\n    } else throw e;\n}","preventionTips":["Default to internal cache dirs; treat external as optional","Validate permissions and mount state before creating directories","Keep one proxy instance and one cache dir per app"],"tags":["filesystem","permissions","storage","proxy-cache"],"backgroundTag":null,"analyzedSha":"e5d74d3aa9d7fb1393a879e33ee380f8f41354f1","analyzedAt":"2026-08-14T11:56:11.997Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}