{"record":{"id":"71c1fd8d3af33794","repo":"TeamNewPipe/NewPipe","slug":"cannot-get-the-parcelfiledescriptor-for","errorCode":null,"errorMessage":"Cannot get the ParcelFileDescriptor for ","messagePattern":"Cannot get the ParcelFileDescriptor for ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/us/shandian/giga/io/FileStreamSAF.java","lineNumber":35,"sourceCode":"public class FileStreamSAF extends SharpStream {\n\n    private final FileInputStream in;\n    private final FileOutputStream out;\n    private final FileChannel channel;\n    private final ParcelFileDescriptor file;\n\n    private boolean disposed;\n\n    public FileStreamSAF(@NonNull ContentResolver contentResolver, Uri fileUri) throws IOException {\n        // Notes:\n        // the file must exists first\n        // ¡read-write mode must allow seek!\n        // It is not guaranteed to work with files in the cloud (virtual files), tested in local storage devices\n\n        file = contentResolver.openFileDescriptor(fileUri, \"rw\");\n\n        if (file == null) {\n            throw new IOException(\"Cannot get the ParcelFileDescriptor for \" + fileUri.toString());\n        }\n\n        in = new FileInputStream(file.getFileDescriptor());\n        out = new FileOutputStream(file.getFileDescriptor());\n        channel = out.getChannel();// or use in.getChannel()\n    }\n\n    @Override\n    public int read() throws IOException {\n        return in.read();\n    }\n\n    @Override\n    public int read(byte[] buffer) throws IOException {\n        return in.read(buffer);\n    }\n\n    @Override","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/TeamNewPipe/NewPipe/blob/9e8be091560a69f35d44bd252eb00bc7911c977b/app/src/main/java/us/shandian/giga/io/FileStreamSAF.java#L17-L53","documentation":"Thrown by FileStreamSAF's constructor when ContentResolver.openFileDescriptor(fileUri, \"rw\") returns null. A null ParcelFileDescriptor means the provider could not open the document for read-write seekable access — the provider exists but refused the mode, the URI is stale, or the file is a virtual (cloud) document that cannot be opened as a raw file descriptor. The comment in-source explicitly notes read-write seek mode is required and cloud virtual files are unsupported.","triggerScenarios":"new FileStreamSAF(contentResolver, fileUri) where openFileDescriptor(fileUri, \"rw\") returns null. Occurs when the URI lacks read/write permission, the provider does not support 'rw' mode (some cloud providers), the document was deleted, or the URI is a virtual file requiring a different stream type.","commonSituations":"Trying to write to a cloud-provider (Drive/Dropbox) document via SAF; the persistable permission on the URI expired or was revoked; the file was deleted between selection and write; a provider that only supports 'r' mode; opening a virtual file (Google Docs) that has no raw byte representation.","solutions":["Ensure the URI was opened with both read and write persistable permissions.","Avoid SAF URIs from cloud providers for seekable read-write; prefer local file:// paths or local-storage SAF trees.","Verify the document still exists (DocumentFile.fromSingleUri(...).exists()) before opening the descriptor.","Catch IOException and fall back to a file://-based FileStream if the content is available on local storage."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify the URI can be opened in 'rw' mode before constructing:\nParcelFileDescriptor pfd = contentResolver.openFileDescriptor(fileUri, \"rw\");\nif (pfd == null) {\n    throw new IOException(\"Cannot open \" + fileUri + \" in read-write seekable mode\");\n}\npfd.close(); // will be reopened by FileStreamSAF","typeGuard":null,"tryCatchPattern":"try {\n    FileStreamSAF stream = new FileStreamSAF(contentResolver, fileUri);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Cannot get the ParcelFileDescriptor\")) {\n        // provider won't give rw fd — fall back to file:// path if available\n        stream = new FileStream(localPath);\n    } else throw e;\n}","preventionTips":["Avoid using SAF URIs from cloud providers for seekable read-write access.","Confirm read+write persistable permissions are held on the URI.","Prefer local file:// paths for download writing; use SAF only for final user-visible output."],"tags":["android-saf","io","storage","parcel-file-descriptor","uri-permission"],"backgroundTag":null,"analyzedSha":"9e8be091560a69f35d44bd252eb00bc7911c977b","analyzedAt":"2026-08-14T00:11:33.519Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}