Skip to content

Subtitle Repair

Subtitle Repair fixes damage that older Sublarr builds wrote into subtitles on disk, and finds saved subtitles that belong to another episode. It lives under Settings → System → Subtitle repair.

Two kinds of damage are repaired:

  • Missing words. An old hearing-impaired cleanup bug deleted ordinary words from non-English subtitles (issue #156).
  • Letters saved as ”�”. A subtitle a provider delivered in an older encoding (Windows-1250/1251/1252, Greek, Cyrillic, Chinese GBK, …) was saved with every umlaut, accent or non-Latin letter replaced by ”�”.

The lost text is gone from the files, so neither can be fixed in place — the repair brings the pristine original back and takes over only what it can prove.

Scan compares each tracked sidecar against the hash recorded when it was downloaded, looks for ”�” in it, and checks whether a provably clean .bak exists. Nothing is fetched from any provider. The Language selector restricts the scan and the repair to one language.

Scan resultMeaning
DamagedThe processing pipeline rewrote this file after download, or it contains ”�”. Includes harmless rewrites (quote normalisation, timing sync) — whether words are actually missing is only knowable by fetching the original.
From backup (free)A .bak exists that provably is the pristine original. Repairing these costs no provider quota. A file with ”�” never counts here: its .bak was copied from the damaged file.
Needs a re-downloadThe original must be re-fetched from the provider it came from.
Already repairedRecorded from an earlier run — repaired or confirmed intact — and skipped.
Partly repairedRepaired, but lines you edited since the download still contain ”�” and need fixing by hand. The affected files are listed.

Files that are skipped without being listed:

  • A sidecar quarantined as another episode’s subtitle. Restoring it would make the wrong subtitle look genuine again.
  • A file whose downloaded original already proved nothing (see below), until the file changes on disk.

Nothing is overwritten on a hunch. For every file, the repair:

  1. Fetches the exact original — by the provider file id stored at download time, never by searching again. A pristine .bak is used instead where one survived.
  2. Proves the original against the file on disk.
    • Missing words: the old buggy pipeline is replayed over the original. The result must reproduce the file on your disk byte-exact. That proves both that it is the right original and that nobody hand-edited the file since. Because the pipeline was configurable per series, every variant that was possible is tried.
    • Letters saved as ”�”: every line is checked on its own. The letters are taken over only where the line matches the original exactly apart from the ”�”. Lines edited since keep their ”�”, and the file is reported as Partly restored.
  3. Keeps your timings. The damage was purely textual, and your files may have been synced against the video since — the on-disk timings win. Cues the old HI pipeline deleted entirely are rebuilt from a time model fitted to the surviving cues. Nothing is re-synced.

If the proof fails, the file is reported as unprovable and left untouched: a failed replay cannot distinguish “you edited this file” from “the provider changed the file”, and the tool does not guess. A file whose downloaded original proved nothing is remembered and only checked again once it has changed on disk, so later runs do not spend quota on it again.

Files the pipeline touched but never damaged (only quotes normalised or timings synced) are recorded as intact and never fetched again.

Every file without a clean .bak costs one provider download against the daily allowance (e.g. 1,000/day on OpenSubtitles for VIP accounts). Every run restores the free files from backups first.

RunDownloadsWrites
Dry runNoneNothing — shows what a backup can repair for free and what would need a provider download.
Backups onlyNoneRestores every file a pristine backup can repair and stops; files that need a download are deferred, so the provider allowance stays with the wanted search.
Start repairOne per file without a backupRestores from backups first, then downloads the rest, provider by provider. Records repaired files, intact files and progress.

A full repair over a large library usually exceeds one day’s allowance. When one provider’s allowance runs out, its remaining files are deferred and the pass carries on with the other providers. The pass then schedules itself for the moment that allowance resets (a few minutes after it, to allow for clock drift) — the panel shows the time. It continues unattended, across container restarts, until a pass finishes without hitting the quota. Nothing is downloaded twice.

A file that cannot be written (a read-only folder, for example) fails on its own; the pass continues with the next one.

FieldMeaning
RestoredFiles repaired completely (text brought back, timings kept).
Partly restoredLetters restored where the lines could be proven; edited lines still contain ”�”.
From backupRestored from a .bak at zero quota cost.
Unprovable (skipped)The original could not be proven against the file — left untouched.
Deferred (needs a download)Needed a download this run did not make: backups-only run, dry run, or the provider’s allowance ran out.
FailedFetch or write error; the file is retried on the next run.

Subtitles saved before Sublarr checked the season and episode of every result can belong to another episode — season 1’s twelfth episode saved for S02E12, for example. A search never looks at a saved subtitle again, so the panel Subtitles of another episode below the repair finds them by the release name the download won with.

  • Check lists every saved automatic download whose release names a different season or episode. It reads the database and file names only and downloads nothing.
  • The check uses Sonarr’s absolute numbers and episode titles, as the search does. A release whose title Sonarr assigns to another season is listed too (Dr Stone - Science Future - 10 is season 4, so it is wrong for S03E10). Only an explicit contradiction counts: a name without numbering, a bare number the season may own, or a bare number under “Part 2” (only the split of the season says which episode that is) is left alone, and so is a hash match.
  • Search again blocks each listed subtitle for that episode only — it stays available for the episode it belongs to — and moves its file to the subtitle trash, where you can restore it. Each series is rescanned once and the episodes go back on the wanted list. The same bytes from another provider are refused.

Manual uploads, extracted tracks and subtitles you edited are never touched. A quarantined file restored from the trash yourself stays where you put it.

EndpointEffect
GET /api/v1/repair/scan?language=deScan report, optionally restricted to one language. Free.
POST /api/v1/repair/runStart a pass. Body: {"language": "de", "dry_run": false, "local_only": false, "limit": 25} — all fields optional; local_only is the backups-only run, limit caps the number of files. 409 while a pass is running.
GET /api/v1/repair/statusProgress of the running (or last) pass, including the auto-resume time.
GET /api/v1/repair/wrong-episodes?language=deSaved subtitles whose release names another episode. Downloads and changes nothing.
POST /api/v1/repair/wrong-episodes/requeueBody: {"language": "de"} (optional). Recomputes the findings on the server, quarantines them and requeues the episodes. 409 while a requeue is running.