lingochamp/FileDownloader · error · IllegalStateException
If you start the task manually, it means this task doesn't…
Error message
If you start the task manually, it means this task doesn't belong to a queue, so you must not invoke BaseDownloadTask#ready() or InQueueTask#enqueue() before you start() this method. For detail: If this task doesn't belong to a queue, what is just an isolated task, you just need to invoke BaseDownloadTask#start() to start this task, that's all. In other words, If this task doesn't belong to a queue, you must not invoke BaseDownloadTask#ready() method or InQueueTask#enqueue() method before invoke BaseDownloadTask#start(), If you do that and if there is the same listener object to start a queue in another thread, this task may be assembled by the queue, in that case, when you invoke BaseDownloadTask#start() manually to start this task or this task is started by the queue, there is an exception buried in there, because this task object is started two times without declare BaseDownloadTask#reuse() : 1. you invoke BaseDownloadTask#start() manually; 2. the queue start this task automatically.
What it means
DownloadTask.start() throws this IllegalStateException when the task was already enqueued into a queue (mIsInQueueTask is true) but the user also calls start() manually. The library forbids manually starting a task that belongs to a FileDownloadQueueSet, because the task may otherwise be started twice (once by the queue, once manually) without a reuse() call.
Solutions
- Do not call start() on tasks added to a queue set; start the queue set instead (queueSet.start()).
- If the task must run standalone, create it without enqueue() and call FileDownloader.getImpl().start(task).
- If you genuinely need to reuse the same task object, call task.reuse() before restarting.
Example fix
// before queueSet.enqueue(task); FileDownloader.getImpl().start(task); // after queueSet.enqueue(task); queueSet.start();
Defensive patterns
Strategy: validation
Validate before calling
if (task instanceof FileDownloadQueueSetMember || taskBelongsToQueueSet(task)) {
queueSet.start();
} else {
FileDownloader.getImpl().start(task);
} Type guard
boolean isStandalone(BaseDownloadTask t) { return t != null && !isEnqueuedInQueueSet(t); } Prevention
- Never mix manual start() with queue enqueue() on the same task instance.
- Start the queue set itself, not individual member tasks.
- Track task ownership (queued vs standalone) in your app's state.
When it happens
Trigger: Calling FileDownloader.getImpl().start(task) (or task.start()) on a task that was added to a FileDownloadQueueSet via enqueue() and then started by queue.start().
Common situations: Developers mixing queue-based and standalone APIs on the same task object, e.g. adding tasks to a queue set then also calling start() directly, or holding a shared task instance started in two threads.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- This task is running
- This task is dirty to restart, If you want to reuse this…
- the provided mPath[ ] is invalid, can't find its directory
- Create parent directory failed, please make sure you have…
- Sorry, FileDownloader can not block the main thread…
AI-assisted analysis of lingochamp/FileDownloader@6237a8cac1 (2026-09-08).
Data as JSON: /api/errors/9fe0a47ec50f6eac.
Report an issue: GitHub.
Appendix: source
Thrown at library/src/main/java/com/liulishuo/filedownloader/DownloadTask.java:291
@Override
public boolean isRunning() {
//noinspection SimplifiableIfStatement
if (FileDownloader.getImpl().getLostConnectedHandler().isInWaitingList(this)) {
return true;
}
return FileDownloadStatus.isIng(getStatus());
}
@Override
public boolean isAttached() {
return mAttachKey != 0;
}
@Override
public int start() {
if (mIsInQueueTask) {
throw new IllegalStateException("If you start the task manually, it means this task "
+ "doesn't belong to a queue, so you must not invoke BaseDownloadTask#ready() "
+ "or InQueueTask#enqueue() before you start() this method. For detail: If this"
+ " task doesn't belong to a queue, what is just an isolated task, you just "
+ "need to invoke BaseDownloadTask#start() to start this task, that's all. In"
+ " other words, If this task doesn't belong to a queue, you must not invoke"
+ " BaseDownloadTask#ready() method or InQueueTask#enqueue() method before"
+ " invoke BaseDownloadTask#start(), If you do that and if there is the same"
+ " listener object to start a queue in another thread, this task may be "
+ "assembled by the queue, in that case, when you invoke "
+ "BaseDownloadTask#start() manually to start this task or this task is started"
+ " by the queue, there is an exception buried in there, because this task"
+ " object is started two times without declare BaseDownloadTask#reuse() :"
+ " 1. you invoke BaseDownloadTask#start() manually; "
+ " 2. the queue start this task automatically.");
}
return startTaskUnchecked();
}View on GitHub (pinned to 6237a8cac1)