TeamNewPipe/NewPipe · warning · IOException
No write permissions on {}
Error message
No write permissions on {} What it means
Thrown by DownloadSettingsFragment when the user-selected Storage Access Framework (SAF) tree URI, after being granted URI permission and wrapped in a StoredDirectoryHelper, reports canWrite() == false. The fragment treats this as an IOException, logs it, and shows a 'no available directory' dialog. The message includes the offending URI.
Source
Thrown at app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java:242
// revoke permissions on the old save path (required for SAF only)
final Context context = requireContext();
forgetSAFTree(context, defaultPreferences.getString(key, ""));
if (!FilePickerActivityHelper.isOwnFileUri(context, uri)) {
// steps to acquire the selected path:
// 1. acquire permissions on the new save path
// 2. save the new path, if step(2) was successful
try {
context.grantUriPermission(context.getPackageName(), uri,
StoredDirectoryHelper.PERMISSION_FLAGS);
final StoredDirectoryHelper mainStorage =
new StoredDirectoryHelper(context, uri, null);
Log.i(TAG, "Acquiring tree success from " + uri.toString());
if (!mainStorage.canWrite()) {
throw new IOException("No write permissions on " + uri.toString());
}
} catch (final IOException err) {
Log.e(TAG, "Error acquiring tree from " + uri.toString(), err);
showMessageDialog(R.string.general_error, R.string.no_available_dir);
return;
}
} else {
final File target = Utils.getFileForUri(uri);
if (!target.canWrite()) {
showMessageDialog(R.string.download_to_sdcard_error_title,
R.string.download_to_sdcard_error_message);
return;
}
uri = Uri.fromFile(target);
}
defaultPreferences.edit().putString(key, uri.toString()).apply();
updatePreferencesSummary();View on GitHub (pinned to 9e8be09156)
Solutions
- Pick a different directory the app can actually write to (e.g. internal storage or a writable SD card partition).
- Ensure takePersistableUriPermission is called for the granted URI so permission survives restarts.
- Verify the storage volume is mounted and writable before selecting it.
- If using an SD card, confirm the card is not read-only or corrupted.
- On older Android versions targeting SD card writing, use the legacy file-based path instead of SAF where applicable.
Defensive patterns
Strategy: validation
Validate before calling
context.grantUriPermission(context.getPackageName(), uri, StoredDirectoryHelper.PERMISSION_FLAGS);
final StoredDirectoryHelper mainStorage = new StoredDirectoryHelper(context, uri, null);
if (!mainStorage.canWrite()) {
// show error dialog; do not persist this path
} Try / catch
try {
final StoredDirectoryHelper mainStorage = new StoredDirectoryHelper(context, uri, null);
if (!mainStorage.canWrite()) {
throw new IOException("No write permissions on " + uri.toString());
}
} catch (final IOException err) {
showMessageDialog(R.string.general_error, R.string.no_available_dir);
} Prevention
- Call takePersistableUriPermission for the chosen SAF tree so access survives restarts.
- Verify canWrite() before persisting the chosen path.
- Prefer internal storage or a known-writable SD card partition.
- Guide the user to pick a writable location in the picker.
When it happens
Trigger: In the SAF picker callback (onActivityResult path), the chosen directory URI is granted permission and a StoredDirectoryHelper is constructed for it, but mainStorage.canWrite() returns false. This happens when the SAF permission grant did not actually confer write access, or the selected location is read-only.
Common situations: User picks a directory on external/removable storage that the app cannot write to (e.g. a read-only SD card partition, a cloud provider root via SAF, or a directory the system did not grant persistable URI permission for), the SAF permission was not persisted across restarts, or the chosen tree is on a storage volume not mounted as writable. Also when the URI refers to a location whose underlying filesystem is read-only.
Related errors
- Cache dir does not exist >
- path to pending downloads are not accessible
- JSON doesn't contain "tabs" array
- Failed to create the tree from Uri
- Cannot create the file
AI-assisted analysis of TeamNewPipe/NewPipe@9e8be09156 (2026-08-14).
Data as JSON: /api/errors/0ca1e439b859c6f0.
Report an issue: GitHub.