Two cases the resume plan already routed to the download stage, but which the
stage could not actually fix.
yt-dlp's overwrites default is off (existing_video_file passes
default_overwrite=False), so an existing target is reported as "already
downloaded" and skipped. A truncated video.mkv was therefore planned for
re-download, never re-downloaded, and re-probed as the same corrupt file --
a job that reports success on media it could not read.
A .part without its .aria2 control file is a sparse file, not a valid prefix,
because aria2 writes its segments out of order. continuedl would resume from
its length and produce a video that silently stops being the source partway
through. Re-downloading is the cheaper mistake, so orphans go unconditionally;
a .part with its control file is left for aria2 to resume, and the sweep runs
once before the retry loop rather than between attempts.
find_video now matches only the merged output. Per-format streams from a
failed merge sort ahead of video.mkv and hold one stream each, so it could
return a video-only file to the audio stage.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>