TeamNewPipe/NewPipe · error · RuntimeException
Cache dir does not exist >
Error message
Cache dir does not exist >
What it means
Thrown by StateSaver when the cache directory path (cacheDirPath) passed to the save routine does not exist as a file/directory on disk. StateSaver persists download/playback state to a cache directory; it first checks cacheDir.exists() and throws a RuntimeException if false. This is a hard precondition: the parent cache path must already exist before state can be saved into a subdirectory beneath it.
Source
Thrown at app/src/main/java/org/schabi/newpipe/util/StateSaver.java:228
final LinkedList<Object> savedObjects = new LinkedList<>();
writeRead.writeTo(savedObjects);
if (isChangingConfig) {
if (savedObjects.size() > 0) {
STATE_OBJECTS_HOLDER.put(prefixFileName, savedObjects);
return new SavedState(prefixFileName, "");
} else {
if (MainActivity.DEBUG) {
Log.d(TAG, "Nothing to save");
}
return null;
}
}
try {
File cacheDir = new File(cacheDirPath);
if (!cacheDir.exists()) {
throw new RuntimeException("Cache dir does not exist > " + cacheDirPath);
}
cacheDir = new File(cacheDir, CACHE_DIR_NAME);
if (!cacheDir.exists()) {
if (!cacheDir.mkdir()) {
if (BuildConfig.DEBUG) {
Log.e(TAG,
"Failed to create cache directory " + cacheDir.getAbsolutePath());
}
return null;
}
}
final File file = new File(cacheDir, prefixFileName
+ (TextUtils.isEmpty(suffixFileName) ? ".cache" : suffixFileName));
if (file.exists() && file.length() > 0) {
// If the file already exists, just return it
return new SavedState(prefixFileName, file.getAbsolutePath());
} else {View on GitHub (pinned to 9e8be09156)
Solutions
- Use context.getCacheDir() (internal, always available) as the cache path rather than external storage.
- Recreate the cache directory (mkdirs) before passing the path to StateSaver if it may have been removed.
- Catch the RuntimeException and skip state-saving gracefully (state is cache; loss is non-fatal).
- Validate cacheDir.exists() and fall back to an alternate location at app startup.
Example fix
// before
File cacheDir = new File(cacheDirPath);
if (!cacheDir.exists()) {
throw new RuntimeException("Cache dir does not exist > " + cacheDirPath);
}
// after — recreate or fall back
File cacheDir = new File(cacheDirPath);
if (!cacheDir.exists() && !cacheDir.mkdirs()) {
cacheDir = context.getCacheDir(); // internal fallback
}
if (!cacheDir.exists()) {
return null; // state-saving is best-effort
} Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the cache directory exists before StateSaver uses it:
File cacheDir = new File(cacheDirPath);
if (!cacheDir.exists() && !cacheDir.mkdirs()) {
cacheDirPath = context.getCacheDir().getAbsolutePath(); // internal fallback
} Try / catch
try {
SavedState state = StateSaver.saveState(...);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Cache dir does not exist")) {
// cache is gone — state saving is best-effort, skip silently
Log.w(TAG, "Cache dir missing, skipping state save", e);
} else throw e;
} Prevention
- Prefer context.getCacheDir() (internal, always available) for state files.
- Create the cache directory with mkdirs() at app startup.
- Treat StateSaver failures as non-fatal since it is cache-only data.
When it happens
Trigger: StateSaver.saveState or the underlying method receives a cacheDirPath whose File does not exist(). The check at line 226 fails. Occurs when the external cache dir (getExternalFilesDir result) was on a just-unmounted SD card, when the app's cache was cleared by the OS under storage pressure, or when an invalid/nonexistent path was configured.
Common situations: Removable storage unmounted between sessions; the OS purged the app's cache directory; a path pointing to external storage that isn't mounted on this device; running on a device where getExternalFilesDir returned a path that was then removed.
Related errors
- path to pending downloads are not accessible
- No write permissions on {}
- Failed to create the tree from Uri
- Cannot create the file
- SAF not available
AI-assisted analysis of TeamNewPipe/NewPipe@9e8be09156 (2026-08-14).
Data as JSON: /api/errors/8ce25fc2284de9d8.
Report an issue: GitHub.