lingochamp/FileDownloader · error · RuntimeException

found invalid internal destination path

Error message

found invalid internal destination path[%s], & path is directory[%B]

What it means

FileDownloadUtils.createOutputStream throws this RuntimeException when the target download path already exists and is a directory instead of a regular file. The library requires the destination path to be a creatable/writable file, so it aborts with a formatted message showing the path and the isDirectory flag.

Solutions

  1. Print the computed path with FileDownloadUtils.generateFilePath(id) and confirm it ends in a file name, not a directory.
  2. Remove the existing directory at that path (or pick a different destination path) before retrying the download.
  3. If supplying a custom path, ensure you pass a full file path (e.g. /sdcard/Download/myfile.apk), not a directory.
  4. Check that no other code in the app creates a directory at the same path used as the download destination.

Example fix

// before
request.setPath(Environment.getExternalStorageDirectory() + "/Download/");
// after
File dest = new File(context.getExternalFilesDir(null), "myfile.apk");
if (dest.isDirectory()) {
    dest.delete();
}
request.setPath(dest.getAbsolutePath());
Defensive patterns

Strategy: validation

Validate before calling

File dest = new File(path);
if (dest.exists() && dest.isDirectory()) {
    dest.delete(); // or choose another path
}

Try / catch

try {
    downloader.create(path);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().contains("invalid internal destination path")) {
        new File(path).delete();
        // retry or pick alternate path
    }
}

Prevention

When it happens

Trigger: Calling download APIs (e.g. FileDownloader.get(...).create() or start()) whose computed destination path (via FileDownloadUtils.generateFilePath or a custom path passed to FileDownloadRequest/setPath) resolves to an existing directory, or a path whose filename component is empty so the path is a directory.

Common situations: Developers set a custom download path ending in '/' or omitting a filename, point two downloads at the same directory path, or reuse a path previously created via mkdir(). Storage-mount changes (SD card swapped) can also leave a directory where a file was expected.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of lingochamp/FileDownloader@6237a8cac1 (2026-09-08). Data as JSON: /api/errors/9dfa843130efa254. Report an issue: GitHub.

Appendix: source

Thrown at library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadUtils.java:697

    public static FileDownloadOutputStream createOutputStream(final String path)
            throws IOException {

        if (TextUtils.isEmpty(path)) {
            throw new RuntimeException("found invalid internal destination path, empty");
        }

        //noinspection ConstantConditions
        if (!FileDownloadUtils.isFilenameValid(path)) {
            throw new RuntimeException(
                    FileDownloadUtils.formatString("found invalid internal destination filename"
                            + " %s", path));
        }

        File file = new File(path);

        if (file.exists() && file.isDirectory()) {
            throw new RuntimeException(
                    FileDownloadUtils.formatString("found invalid internal destination path[%s],"
                            + " & path is directory[%B]", path, file.isDirectory()));
        }
        if (!file.exists()) {
            if (!file.createNewFile()) {
                throw new IOException(
                        FileDownloadUtils.formatString("create new file error  %s",
                                file.getAbsolutePath()));
            }
        }

        return CustomComponentHolder.getImpl().createOutputStream(file);
    }

    public static boolean isBreakpointAvailable(final int id, final FileDownloadModel model) {
        return isBreakpointAvailable(id, model, null);
    }

View on GitHub (pinned to 6237a8cac1)