Document data-loss incident, pause qbt-relink.sh

Babylon 5 S03/S04 (44 episodes) were destroyed during a relink
attempt despite every safety check the script performs (HTTP status,
save_path, content_path) passing. qBittorrent's own automatic
incomplete-file management took further unrequested action after
the script's calls succeeded - moving/truncating files at a
location it still considered incomplete - which none of the
script's checks could see coming since they only verify immediately
after its own calls.

No backup existed. Files could not be found anywhere on /data after
a full search. Marking qbt-relink.sh unsafe until the interaction
with qBittorrent's temp_path_enabled behavior is understood well
enough to prevent this.

Claude-Session: https://claude.ai/code/session_01HZQK6jHmdTpFjFZM8FUnqA
This commit is contained in:
2026-09-08 10:13:07 +00:00
parent 027108b492
commit 49e47a32bf
+60 -1
View File
@@ -5,6 +5,20 @@ description: Use Sonarr to add TV shows and manually import existing raw-named f
# Sonarr library migration/import
**⚠️ `qbt-relink.sh` is currently UNSAFE — do not use it until this warning is
removed.** It caused real, apparently unrecoverable data loss (Babylon 5
seasons 3 and 4, 44 episodes) on 2026-09-08: qBittorrent's own automatic
incomplete-file management fought the script's manual `setLocation` calls
across repeated resume/stop cycles and physically moved/destroyed the real
files, even after every safety check the script performs (stopped state,
confirmed `save_path`, confirmed `content_path`) reported success. See
"Incident 3" below for the full detail. **The Sonarr import workflow itself
(`sonarr.sh scan`/`import`) is unaffected and still safe** — it's specifically
the qBittorrent-side relink step that's paused. Until this is fixed, leave
qBittorrent's stale torrent entries alone after a Sonarr import rather than
touching them — a `missingFiles` error in the qBittorrent UI is a much
smaller problem than what happened here.
This repo's Sonarr manages TV show organization for both Jellyfin and Plex
(they share the same `nas_media` library at `/data/video/tv`). The
`claude-homelab` plugin's Sonarr skill (if installed) only covers
@@ -130,7 +144,52 @@ or its `state` is `checkingDL` instead of `checkingUP`**, check
`content_path` vs `save_path` directly — a mismatch means the recheck is
running against the wrong location and will "succeed" at finding nothing.
### Incident: an unchecked `setLocation` call let a torrent start re-downloading
### Incident 3: qBittorrent's own automatic file management destroyed real data despite every check passing — data loss, `qbt-relink.sh` is now paused
2026-09-08, same overall session, later batch. Even with incidents 1 and 2's
fixes in place (`api_call` status checking, torrent stopped first,
`save_path` *and* `content_path` both confirmed correct before proceeding),
Babylon 5 S03 and S04 lost their actual files. The qBittorrent log
(`/api/v2/log/main`) tells the story: after `setLocation` moved them to
`Season 03`/`Season 04` (logged success), qBittorrent's *own* internal logic
immediately enqueued and executed a further move of those same files **back**
to `/data/torrents/incomplete/video/tv` on its own — nothing in the script
requested this. A later resume cycle moved them back to `Season 03`/`04`
again, but then repeated automatic resume/stop cycles followed (visible as
alternating `"Torrent resumed"`/`"Torrent stopped"` log lines with no
corresponding script action), and after those, both `Season 03` and
`Season 04` folders were **completely empty** — confirmed via `ls`/`stat`
from two separate containers, and a full search of `/data` found the files
nowhere. 44 episodes, gone. No backup existed (the user had explicitly
decided to proceed without one earlier in this project).
Best-guess mechanism: qBittorrent's `temp_path_enabled` incomplete-file
management re-evaluates on every resume, independent of manual
`setLocation`/`setDownloadPath` calls, and can decide to relocate — or,
worse, truncate/overwrite in place expecting fresh downloaded data — files
at a location it still considers "incomplete" (i.e. never successfully
verified as 100% via a *clean* recheck). Since these torrents' recheck kept
getting interrupted/retriggered across multiple attempts (network/NFS
slowness caused several manual re-triggers in this session), the torrent
seems to have never reached a stable "verified complete" state internally,
leaving it perpetually eligible for this automatic (and here, destructive)
relocation — regardless of what the script's own state checks reported.
**This means the safety checks this script relies on (`save_path`,
`content_path`, HTTP status) are necessary but not sufficient** — they
confirm the *script's* requests succeeded, but qBittorrent can still take
further unrequested action afterward that undoes or destroys the result,
and none of that is visible to a script that only checks immediately after
its own calls. `qbt-relink.sh` is paused (see the warning at the top of this
file) until this is understood well enough to prevent it — likely candidates
for a real fix: disabling `temp_path_enabled` globally before relinking
(and confirming no other torrent depends on it) as a global preference, an
approach that fully separates the qBittorrent-tracked download from the
Sonarr-organized library so they never share a path, or verifying via a
polling loop that a recheck reaches a genuinely stable end state (not just
"currently reports 100% right now") before considering a torrent safe.
### Incident 1: an unchecked `setLocation` call let a torrent start re-downloading
The first version of `qbt-relink.sh` fired `setLocation`/`renameFile`/
`recheck` with `curl -s ... > /dev/null`, discarding the HTTP status. Running