Delete subtitle sidecars with their media file #218

Closed
opened 2026-08-25 01:50:43 +01:00 by naps62-yolo · 1 comment
Owner

Deleting a season or an episode leaves its subtitle sidecars on disk with
nothing in the database pointing at them.

remove_library_files in crates/arr-api/src/series.rs resolves targets from
media_files rows, and for FileScope::Season / FileScope::Episode it
deletes the video file itself — only a whole-series delete removes the title
folder. remove_scope_files then deletes the media_files row in the same
transaction, and subtitle_files.media_file_id is ON DELETE CASCADE, so the
subtitle rows vanish while the .srt and .mt.srt files stay.

The result contradicts §7.4's audit-by-ls property in both directions: the
folder shows subtitles arr no longer believes in, and a later re-import fetches
a second copy alongside them.

The doc comment on remove_library_files — "Sidecars beside a removed episode
therefore stay; they are not rows this service wrote" — dates from #174/#175,
before #186 existed. Subtitle sidecars are rows this service wrote now, and
the comment should go with the fix.

Delete a media file's sidecars alongside the file, in the same transaction that
drops its rows.

Found while implementing #195.

Depends on: #186, #195

Deleting a season or an episode leaves its subtitle sidecars on disk with nothing in the database pointing at them. `remove_library_files` in `crates/arr-api/src/series.rs` resolves targets from `media_files` rows, and for `FileScope::Season` / `FileScope::Episode` it deletes the video file itself — only a whole-series delete removes the title folder. `remove_scope_files` then deletes the `media_files` row in the same transaction, and `subtitle_files.media_file_id` is `ON DELETE CASCADE`, so the subtitle rows vanish while the `.srt` and `.mt.srt` files stay. The result contradicts §7.4's audit-by-`ls` property in both directions: the folder shows subtitles arr no longer believes in, and a later re-import fetches a second copy alongside them. The doc comment on `remove_library_files` — "Sidecars beside a removed episode therefore stay; they are not rows this service wrote" — dates from #174/#175, before #186 existed. Subtitle sidecars *are* rows this service wrote now, and the comment should go with the fix. Delete a media file's sidecars alongside the file, in the same transaction that drops its rows. Found while implementing #195. Depends on: #186, #195
naps62-yolo added this to the Subtitles milestone 2026-08-25 01:50:43 +01:00
naps62-yolo added the area/apidifficulty/moderatetype/bugphase/9-subtitles labels 2026-08-25 01:50:43 +01:00
naps62-yolo added a new dependency 2026-08-25 01:50:50 +01:00
Author
Owner

Fixed. remove_library_files (crates/arr-api/src/series.rs) now resolves and unlinks a media file's subtitle_files.path sidecars alongside the video for FileScope::Season and FileScope::Episode, using the same target-resolution pass as the video file, before the transaction that cascades the subtitle_files rows. Updated the stale doc comment that predated #186. Added a subtitle_paths query mirroring scope_paths, and two tests (removing_a_season_takes_its_subtitle_sidecars, removing_one_episode_takes_its_subtitle_sidecar) covering both scope boundaries. No migration needed — no schema change.

Branch: subtitles/218-delete-sidecars

just ci: passed (671 tests, fmt/lint/deps/web-check all green).

Findings

  • crates/arr-subs/src/translate.rs has 4 dead-code functions (strip_code_fence, language_name, variant_note, system_prompt) that trip cargo clippy -p arr-api --all-targets --all-features -- -D warnings when run standalone outside the full just ci invocation — pre-existing, unrelated to #218, not touched here.
Fixed. `remove_library_files` (`crates/arr-api/src/series.rs`) now resolves and unlinks a media file's `subtitle_files.path` sidecars alongside the video for `FileScope::Season` and `FileScope::Episode`, using the same target-resolution pass as the video file, before the transaction that cascades the `subtitle_files` rows. Updated the stale doc comment that predated #186. Added a `subtitle_paths` query mirroring `scope_paths`, and two tests (`removing_a_season_takes_its_subtitle_sidecars`, `removing_one_episode_takes_its_subtitle_sidecar`) covering both scope boundaries. No migration needed — no schema change. Branch: `subtitles/218-delete-sidecars` `just ci`: passed (671 tests, fmt/lint/deps/web-check all green). ## Findings - `crates/arr-subs/src/translate.rs` has 4 dead-code functions (`strip_code_fence`, `language_name`, `variant_note`, `system_prompt`) that trip `cargo clippy -p arr-api --all-targets --all-features -- -D warnings` when run standalone outside the full `just ci` invocation — pre-existing, unrelated to #218, not touched here.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: yolo/arr#218