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
- Print the computed path with FileDownloadUtils.generateFilePath(id) and confirm it ends in a file name, not a directory.
- Remove the existing directory at that path (or pick a different destination path) before retrying the download.
- If supplying a custom path, ensure you pass a full file path (e.g. /sdcard/Download/myfile.apk), not a directory.
- 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
- Always pass full file paths (with filename), never directories.
- Use FileDownloadUtils.generateFilePath(id) to compute destinations.
- Sanitize user-supplied filenames to avoid empty names or trailing slashes.
- Log and verify the destination path before starting downloads.
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
- create new file error
- fetched length[ ] != content length[ ], range[ , ) offset[…
- listener must not be null!
- event must not be null!
- can't create the block complete message for id
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)