MuntashirAkon/AppManager · error · IOException

Target is not backed by a real file

Error message

Target is not backed by a real file

What it means

Thrown by PathImpl.openFileChannel() when the resolved DocumentFile is neither an ExtendedRawDocumentFile nor a VirtualDocumentFile — i.e. a generic SAF document with no real backing file accessible to the process. FileChannel semantics require a real file descriptor, which SAF-only documents cannot provide.

Source

Thrown at app/src/main/java/io/github/muntashirakon/io/PathImpl.java:1269

    public FileChannel openFileChannel(int mode) throws IOException {
        DocumentFile documentFile = resolveFileOrNull(this.documentFile);
        if (documentFile == null) {
            throw new IOException(this.documentFile.getUri() + " is a directory");
        }
        if (documentFile instanceof ExtendedRawDocumentFile) {
            ExtendedFile file = Objects.requireNonNull(getFile());
            if (file instanceof RemoteFile) {
                try {
                    return LocalServices.getFileSystemManager().openChannel(file, mode);
                } catch (RemoteException e) {
                    throw new IOException(e);
                }
            }
            return FileSystemManager.getLocal().openChannel(file, mode);
        } else if (documentFile instanceof VirtualDocumentFile) {
            return ((VirtualDocumentFile) documentFile).openChannel(mode);
        }
        throw new IOException("Target is not backed by a real file");
    }

    @NonNull
    private static Path createFileAsDirectChild(@NonNull Context context,
                                                @NonNull DocumentFile documentFile,
                                                @NonNull String displayName,
                                                @Nullable String mimeType) throws IOException {
        if (displayName.indexOf(File.separatorChar) != -1) {
            throw new IllegalArgumentException("Display name contains file separator.");
        }
        documentFile = getRealDocumentFile(documentFile);
        if (!documentFile.isDirectory()) {
            throw new IOException("Current file is not a directory.");
        }
        String extension = null;
        if (mimeType != null) {
            extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
        } else mimeType = DEFAULT_MIME;

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Use Path.openInputStream()/openOutputStream() instead of openFileChannel for SAF documents
  2. Check the backing type before choosing the channel API
  3. Move files to app-private storage and open a channel there when channel semantics are required
  4. Handle this IOException with a fallback to stream-based copy

Example fix

// before
FileChannel ch = path.openFileChannel(PathUtils.MODE_READ);
// after
FileChannel ch;
try {
    ch = path.openFileChannel(PathUtils.MODE_READ);
} catch (IOException e) {
    try (InputStream in = path.openInputStream()) {
        File tmp = File.createTempFile("vfs", null, context.getCacheDir());
        Files.copy(in, tmp.toPath(), StandardCopyOption.REPLACE_EXISTING);
        ch = FileChannel.open(tmp.toPath(), StandardOpenOption.READ);
    }
}
Defensive patterns

Strategy: fallback

Validate before calling

boolean backed = path.getUri().getScheme().equals("file") || path instanceof RawPath; // choose streams otherwise

Type guard

null

Try / catch

try { return path.openFileChannel(mode); } catch (IOException e) { return copyToCacheAndOpenChannel(path); }

Prevention

When it happens

Trigger: Calling Path.openFileChannel(mode) on a standard content:// document URI (external storage via DocumentsProvider, cloud providers, DownloadsProvider) rather than a raw/virtual-backed path.

Common situations: Files on removable SD card accessed via SAF; documents in Download folder exposed only through DocumentsProvider; cloud-storage documents (Drive) with no local file; trying to use FileChannel-based APIs (mmap, RandomAccessFile-like access) on SAF-only content.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/f655771f7140d86e. Report an issue: GitHub.