Decision log — why was this subtitle chosen?
New in 1.10.0.
When a search picks the “wrong” subtitle — or finds nothing at all — the useful question is not what happened but why. The decision log answers that without digging through log files: every search records its complete selection pipeline, and the result is stored alongside the download.
Where to find it
Section titled “Where to find it”| Situation | Where the log lives | How to open it |
|---|---|---|
| A subtitle was downloaded | With the download | Activity → History → the why? action on the row |
| Nothing was found | On the wanted item | Wanted → the item’s “Why was nothing found?” action |
History rows only show the action when a log actually exists. Entries that predate 1.10.0 have none — the log starts being recorded from this release onwards.
What it records
Section titled “What it records”The log follows the same order the pipeline runs in.
1. Providers
Section titled “1. Providers”For every provider Sublarr either queried or skipped:
- queried — how many candidates came back, and how long it took
- skipped — with the reason:
| Reason | Meaning |
|---|---|
circuit_open | The provider’s circuit breaker is open after repeated failures. See Circuit breaker. |
rate_limited | The provider is in a rate-limit cooldown. |
budget_exhausted | The daily API budget for this provider is used up. |
no_pool_key | No usable API key in the pool — all exhausted, cooling after a 429, or none configured. |
auto_disabled | Sublarr disabled the provider automatically after a sustained failure streak. |
2. Filter stages
Section titled “2. Filter stages”Every candidate that survived the provider stage runs through a chain of filters. The log records, per stage, how many candidates went in, how many came out, and which ones were dropped:
| Stage | Drops a candidate when |
|---|---|
language | The subtitle is not in a requested language. |
format | The format is excluded — e.g. a series that requires ASS. |
min_score | The score is below the profile cutoff or the per-language threshold. |
blacklist | The exact subtitle was blacklisted earlier. |
forced_only | The forced/non-forced flag doesn’t match the request. |
release_group_exclude | The release group is on the blocked list. |
profile_must_contain | The filename lacks a term the profile requires. |
profile_must_not_contain | The filename contains a term the profile forbids. |
3. Download and outcome
Section titled “3. Download and outcome”Download attempts (including retries and which provider served the file), the upgrade decision when an existing subtitle was replaced, and the final pick with its complete score breakdown — every component that contributed points, including release-group bonuses and each penalty-rule hit.
Reading it
Section titled “Reading it”The modal opens on a compact view: which provider won, the final score, and the count of candidates rejected per stage. That is usually enough to answer “why this one”.
Expert mode expands it to the per-candidate detail: every rejected subtitle with its stage and reason, and per-provider timings. This is the view worth copying into a support thread — it is far more useful than a log excerpt, and it contains no credentials.
Turning it off
Section titled “Turning it off”Recording is on by default and costs a JSON snapshot per search. Disable it with decision_log_enabled (Settings → Subtitles → Automation) if you don’t want the storage.
With the setting off, the why? action disappears for new searches; existing logs are kept.
Limits worth knowing
Section titled “Limits worth knowing”- A preview does not record. A dry run deliberately writes nothing at all, including the decision log — it shows its result inline instead.
- Successful downloads store the log with the download, not the wanted item. The wanted row is removed once it is satisfied, so a
not_found,failedorskippedoutcome is what leaves a log behind on the item.
The same payload is available programmatically:
GET /api/v1/history/{download_id}/decisionGET /api/v1/wanted/{item_id}/decisionBoth return 404 with a plain message when no log was recorded for that entry.