lingochamp/FileDownloader · error · IllegalStateException

take block completed snapshot, must has already be…

Error message

take block completed snapshot, must has already be completed. %d %d

What it means

Thrown by MessageSnapshotTaker.takeBlockCompleted when asked to wrap a snapshot whose status is not FileDownloadStatus.completed. Creating a block-complete message only makes sense on an already-completed task; the format args print the offending snapshot's id and its actual status code so you can identify which download reached this path in the wrong state.

Solutions

  1. Ensure takeBlockCompleted is only invoked from the completed-status callback (e.g. BaseDownloadTask#completed) after the task has fully finished
  2. Check snapshot.getStatus() == FileDownloadStatus.completed before calling takeBlockCompleted
  3. Verify the download flow is not re-dispatching an old snapshot after a status transition; use the latest snapshot from the MessageSnapshotGate
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at library/src/main/java/com/liulishuo/filedownloader/message/MessageSnapshotTaker.java:93 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at library/src/main/java/com/liulishuo/filedownloader/message/MessageSnapshotTaker.java:93

            return new LargeMessageSnapshot.ErrorMessageSnapshot(id, sofar, error);
        } else {
            return new SmallMessageSnapshot.ErrorMessageSnapshot(id, (int) sofar, error);
        }
    }

    public static MessageSnapshot catchPause(BaseDownloadTask task) {
        if (task.isLargeFile()) {
            return new LargeMessageSnapshot.PausedSnapshot(task.getId(),
                    task.getLargeFileSoFarBytes(), task.getLargeFileTotalBytes());
        } else {
            return new SmallMessageSnapshot.PausedSnapshot(task.getId(),
                    task.getSmallFileSoFarBytes(), task.getSmallFileTotalBytes());
        }
    }

    public static MessageSnapshot takeBlockCompleted(MessageSnapshot snapshot) {
        if (snapshot.getStatus() != FileDownloadStatus.completed) {
            throw new IllegalStateException(
                    FileDownloadUtils.formatString("take block completed snapshot, must has "
                                    + "already be completed. %d %d",
                            snapshot.getId(), snapshot.getStatus()));
        }

        return new BlockCompleteMessage.BlockCompleteMessageImpl(snapshot);
    }

    public static MessageSnapshot take(byte status, FileDownloadModel model,
                                       DownloadStatusCallback.ProcessParams processParams) {
        final MessageSnapshot snapShot;
        final int id = model.getId();
        if (status == FileDownloadStatus.warn) {
            throw new IllegalStateException(FileDownloadUtils.
                    formatString("please use #catchWarn instead %d", id));
        }

        switch (status) {

View on GitHub (pinned to 6237a8cac1)