{"record":{"id":"adba754899edfa30","repo":"TeamNewPipe/NewPipe","slug":"path-to-pending-downloads-are-not-accessible","errorCode":null,"errorMessage":"path to pending downloads are not accessible","messagePattern":"path to pending downloads are not accessible","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"app/src/main/java/us/shandian/giga/service/DownloadManager.java","lineNumber":89,"sourceCode":"\n        mFinishedMissionStore = new FinishedMissionStore(context);\n        mHandler = handler;\n        mMainStorageAudio = storageAudio;\n        mMainStorageVideo = storageVideo;\n        mMissionsFinished = loadFinishedMissions();\n        mPendingMissionsDir = getPendingDir(context);\n\n        loadPendingMissions(context);\n    }\n\n    private static File getPendingDir(@NonNull Context context) {\n        File dir = context.getExternalFilesDir(DOWNLOADS_METADATA_FOLDER);\n        if (testDir(dir)) return dir;\n\n        dir = new File(context.getFilesDir(), DOWNLOADS_METADATA_FOLDER);\n        if (testDir(dir)) return dir;\n\n        throw new RuntimeException(\"path to pending downloads are not accessible\");\n    }\n\n    private static boolean testDir(@Nullable File dir) {\n        if (dir == null) return false;\n\n        try {\n            if (!Utility.mkdir(dir, false)) {\n                Log.e(TAG, \"testDir() cannot create the directory in path: \" + dir.getAbsolutePath());\n                return false;\n            }\n\n            File tmp = new File(dir, \".tmp\");\n            if (!tmp.createNewFile()) return false;\n            return tmp.delete();// if the file was created, SHOULD BE deleted too\n        } catch (Exception e) {\n            Log.e(TAG, \"testDir() failed: \" + dir.getAbsolutePath(), e);\n            return false;\n        }","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/TeamNewPipe/NewPipe/blob/9e8be091560a69f35d44bd252eb00bc7911c977b/app/src/main/java/us/shandian/giga/service/DownloadManager.java#L71-L107","documentation":"Thrown by DownloadManager.getPendingDir when neither candidate directory for pending-download metadata passes the testDir() check. The method first tries the app's external files dir (getExternalFilesDir(DOWNLOADS_METADATA_FOLDER)), then falls back to internal files dir (getFilesDir() + DOWNLOADS_METADATA_FOLDER); if both fail testDir (null, or Utility.mkdir cannot create/write it), it throws a RuntimeException. This is a fatal init failure: the download manager cannot function without a writable metadata directory.","triggerScenarios":"getPendingDir(context) returns from both branches without a passing dir: getExternalFilesDir returns null (no external storage mounted), and the internal getFilesDir path also fails testDir (Utility.mkdir returns false — rare, indicates filesystem/permission failure on internal storage). The throw at line 89 fires.","commonSituations":"Device with no external storage and a ROM where getExternalFilesDir returns null; internal storage in an error state (disk full, filesystem corruption); a custom ROM permission bug blocking internal dir creation; the app's data directory was partially cleared/corrupted leaving getFilesDir in a bad state.","solutions":["Ensure external storage is available (check Environment.getExternalStorageState) before relying on the external path.","Free internal storage space — a full internal partition can cause mkdir to fail.","Clear the app's data/cache to reset the files directory to a known-good state.","If reproducible on a specific ROM/device, report the getExternalFilesDir-null behavior and add a third fallback (context.getCacheDir) as a last resort."],"exampleFix":"// before\nFile dir = new File(context.getFilesDir(), DOWNLOADS_METADATA_FOLDER);\nif (testDir(dir)) return dir;\nthrown new RuntimeException(\"path to pending downloads are not accessible\");\n\n// after — add cache dir as last-resort fallback\nFile dir = new File(context.getFilesDir(), DOWNLOADS_METADATA_FOLDER);\nif (testDir(dir)) return dir;\ndir = new File(context.getCacheDir(), DOWNLOADS_METADATA_FOLDER);\nif (testDir(dir)) return dir;\nthrow new RuntimeException(\"path to pending downloads are not accessible\");","handlingStrategy":"try-catch","validationCode":"// Before constructing DownloadManager, verify at least one metadata dir is usable:\nFile ext = context.getExternalFilesDir(DOWNLOADS_METADATA_FOLDER);\nif (ext == null || !ext.exists() && !ext.mkdirs()) {\n    File internal = new File(context.getFilesDir(), DOWNLOADS_METADATA_FOLDER);\n    if (!internal.exists() && !internal.mkdirs()) {\n        // warn user: downloads cannot persist on this device state\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    DownloadManager dm = new DownloadManager(context);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"path to pending downloads\")) {\n        // fatal init — notify user that storage is inaccessible\n        showStorageErrorDialog();\n    } else throw e;\n}","preventionTips":["Check Environment.getExternalStorageState() before relying on external paths.","Free internal storage space to avoid mkdir failures.","Clear app data if the files directory is in a corrupt state.","Add a cache-dir fallback in getPendingDir as a last resort."],"tags":["download-manager","storage","init","android","io"],"backgroundTag":null,"analyzedSha":"9e8be091560a69f35d44bd252eb00bc7911c977b","analyzedAt":"2026-08-14T00:11:33.519Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}