MuntashirAkon/AppManager · error · IOException
Could not resolve Uri:
Error message
Could not resolve Uri:
What it means
As the final fallback, openOutputStream() uses context.getContentResolver().openOutputStream(uri, mode) with mode "w" or "wa"; ContentResolver returns null when it cannot open a stream (unknown/unresolvable provider, bad URI, or provider denial), so the method throws IOException("Could not resolve Uri: <uri>"). Unlike a thrown exception from the provider, a null return means the URI could not be turned into a stream at all.
Source
Thrown at app/src/main/java/io/github/muntashirakon/io/PathImpl.java:1220
@NonNull
public OutputStream openOutputStream(boolean append) throws IOException {
DocumentFile documentFile = resolveFileOrNull(this.documentFile);
if (documentFile == null) {
throw new IOException(this.documentFile.getUri() + " is a directory");
}
if (documentFile instanceof ExtendedRawDocumentFile) {
try {
return Objects.requireNonNull(getFile()).newOutputStream(append);
} catch (IOException e) {
throw new IOException("Could not open file for writing: " + documentFile.getUri(), e);
}
} else if (documentFile instanceof VirtualDocumentFile) {
return ((VirtualDocumentFile) documentFile).openOutputStream(append);
}
String mode = "w" + (append ? "a" : "t");
OutputStream os = context.getContentResolver().openOutputStream(documentFile.getUri(), mode);
if (os == null) {
throw new IOException("Could not resolve Uri: " + documentFile.getUri());
}
return os;
}
@NonNull
public InputStream openInputStream() throws IOException {
DocumentFile documentFile = resolveFileOrNull(this.documentFile);
if (documentFile == null) {
throw new IOException(this.documentFile.getUri() + " is a directory");
}
if (documentFile instanceof ExtendedRawDocumentFile) {
try {
return Objects.requireNonNull(getFile()).newInputStream();
} catch (IOException e) {
throw new IOException("Could not open file for reading: " + documentFile.getUri(), e);
}
} else if (documentFile instanceof VirtualDocumentFile) {
return ((VirtualDocumentFile) documentFile).openInputStream();View on GitHub (pinned to 0152f468fc)
Solutions
- Verify the URI is valid and permissions are still held (check persisted URI permissions)
- Re-acquire access via the SAF picker and takePersistableUriPermission(MODE_READ|WRITE)
- Catch the IOException and re-prompt the user to reselect the location
Example fix
// before
OutputStream os = path.openOutputStream();
// after
try {
OutputStream os = path.openOutputStream();
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Could not resolve Uri")) {
// re-request SAF access
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// ensure persisted SAF permission
for (UriPermissions p : context.getContentResolver().getPersistedUriPermissions()) {
if (p.getUri().equals(treeUri) && p.isWritePermission()) return;
}
throw new IOException("No persisted write permission for " + treeUri); Try / catch
try {
OutputStream os = path.openOutputStream(append);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Could not resolve Uri")) {
// re-acquire access via SAF picker
} else throw e;
} Prevention
- Call takePersistableUriPermission after every SAF result
- Handle FLAG_GRANT_PERSISTABLE across reboots
- Validate the URI still exists before opening streams
When it happens
Trigger: Calling openOutputStream on a Path whose documentFile is neither ExtendedRawDocumentFile nor VirtualDocumentFile, and ContentResolver.openOutputStream returns null — invalid or revoked document URI, unsupported provider, or permission not granted/persisted.
Common situations: Using a document URI after the SAF permission grant was revoked or the device rebooted without takePersistableUriPermission, or a Uri from a different app/provider that no longer exists.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- Unable to open output stream.
- Could not create directory named
- Target is not backed by a real file
- Could not create directory
- Could not get backup files.
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/251d34e42b66c203.
Report an issue: GitHub.