MuntashirAkon/AppManager · error · IOException

Either source or destination are a mount point.

Error message

Either source or destination are a mount point.

What it means

copyFile() refuses to copy when either the source or destination Path is a mount point (VirtualFileSystem root or other mounted location), throwing IOException("Either source or destination are a mount point."). Copying across/onto mount boundaries through this code path is unsupported and could bypass the virtual filesystem's isolation.

Solutions

  1. Copy to/from a path inside the mount rather than the mount root itself
  2. Copy the mount point's contents recursively instead of the mount point as a unit
  3. Check isMountPoint() on both paths beforehand and route to an alternative copy mechanism

Example fix

// before
IoUtils.copy(mountRootPath, dst);
// after
if (mountRootPath.isMountPoint() || dst.isMountPoint()) {
    throw new IllegalArgumentException("Choose a non-mount-point source/destination");
}
IoUtils.copy(mountRootPath, dst);
Defensive patterns

Strategy: validation

Validate before calling

if (src.isMountPoint() || dst.isMountPoint()) {
    throw new IllegalArgumentException("Copy must not target or originate at a mount point");
}

Try / catch

try {
    // copy operation
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().contains("mount point")) {
        // switch to a path inside the mount instead of its root
    } else throw e;
}

Prevention

When it happens

Trigger: Calling copy operations (copyInOut/copyFile via PathImpl static helpers, or Path.copy variants that route here) where src.isMountPoint() or dst.isMountPoint() returns true — e.g. src or dst is a VFS root like a remote/SAF mount root.

Common situations: Copying from/to the root of a mounted remote filesystem (FTP/SMB/SAF custom mounts in this library), or pointing a destination directly at a mount root instead of a file inside it.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

                copyFile(context, source, newPath);
                return new PathImpl(context, newPath);
            } catch (IOException e) {
                Log.d(TAG, "Could not copy files.", e);
                return null;
            }
        }
        Log.d(TAG, "Unknown error during copying.");
        return null;
    }

    private static void copyFile(@NonNull Context context, @NonNull DocumentFile src, @NonNull DocumentFile dst)
            throws IOException {
        copyFile(new PathImpl(context, src), new PathImpl(context, dst));
    }

    private static void copyFile(@NonNull Path src, @NonNull Path dst) throws IOException {
        if (src.isMountPoint() || dst.isMountPoint()) {
            throw new IOException("Either source or destination are a mount point.");
        }
        IoUtils.copy(src, dst);
    }

    // Copy directory content
    private static void copyDirectory(@NonNull Context context, @NonNull DocumentFile src, @NonNull DocumentFile dst,
                                      boolean override) throws IOException {
        copyDirectory(new PathImpl(context, src), new PathImpl(context, dst), override);
    }

    private static void copyDirectory(@NonNull Context context, @NonNull DocumentFile src, @NonNull DocumentFile dst)
            throws IOException {
        copyDirectory(new PathImpl(context, src), new PathImpl(context, dst), true);
    }

    private static void copyDirectory(@NonNull Path src, @NonNull Path dst, boolean override) throws IOException {
        for (Path file : src.listFiles()) {
            String name = file.getName();

View on GitHub (pinned to 0152f468fc)