2026-07-20 Plex Skip Credits Investigation
What I set out to do
Work out why there was no “Skip Credits” button on the One Piece episodes I’d just watched. Expected a quick settings answer.
What I actually did
Not a settings answer. Went from symptom to root cause through the Plex API, the library SQLite DB, the server logs, and eventually strings on the binaries.
Root cause: Plex’s credits detector only samples the final ~10% of runtime (-ss 1288 on a 1431s file), and One Piece’s ED sits at 1216-1306s with a post-credits scene and next-episode preview after it. The detector sees 18 seconds of a 90-second sequence, crashes, and permanently gives up after four tries. Full write-up in 2026-07-20 Plex Credits Detection Only Scans the Last 10 Percent.
Detours worth noting. My first fix (/analyze across 46 episodes) returned 200 on every request and did nothing at all — caught only because I’d snapshotted markers first and diffed. I also chased an audio-codec correlation that turned out to be incidental. And I initially told Adam there was one viable tool when there were three, which only came out after being asked to search properly rather than assert.
Ended with a batch correction built from each file’s own Credits chapters, applied to all 23 episodes and verified against the API. An earlier attempt was blocked by the permission classifier mid-run; stopped Plex for it and brought the server straight back up rather than leaving it down while sorting out permissions.
What was striking
The correct data was already inside the Plex database, one column away from the thing that was empty. The files ship named chapter markers, Plex parsed them into pv:chapters, stored them in the same media_parts row, and then failed to detect the credits it had already been told about.
Also: the tool with the most search results and forum recommendations for this exact problem (plex-credits-detect) has been dead since 2022. Checking pushed_at before trusting a recommendation is cheap and would have saved a wrong answer.
Being pushed to “confirm there is no other solution” was the useful correction of the session. The confident answer was too narrow, and searching the angles I’d skipped turned up PlexAutoSkip, which solves it with no database writes at all.
Where this landed
Season 22 is clean: 42 markers aligned to chapter data, 0 that fire during content, 21 harmless end-of-file stubs left in place, 6 episodes unverifiable because their files carry no Credits chapter. 26 episodes now hold chapter-derived markers at pv:version=5, which also stops Plex’s v4 detector regenerating over them.
Deliberately not automating this. New episodes will keep hitting the same trap, and the options are known (PlexAutoSkip on chapter names, scripting the chapter→marker step, or periodic manual passes via MarkerEditorForPlex) — but the backlog was the actual annoyance and it’s cleared. Revisit when it becomes irritating again.
Still unverified: whether the button renders during playback. Everything below the player is correct; nobody has watched S22E12 at 20:18 to confirm the last link in the chain.
Related
2026-07-20 Plex Credits Detection Only Scans the Last 10 Percent, Homelab Services Architecture
2026-07-20 Reviewing PR #48 — Verifying Findings Instead of Asserting Them
What I set out to do
Second session, unrelated to the Plex work above. Started as branch/PR housekeeping on achhina/media-stack, turned into a full review of Amir Mohamed’s PR #48 (WSL2-compat and manga-stack fixes for the declarative stack).
What I actually did
Pruned the branch backlog first: 17 local / 33 remote down to 3 / 5. Closed PR #34 and issue #32 as superseded — the Terraform layer-2 investigation they tracked had already shipped via #43–#47 (see Media Stack IaC Declarative Config Evaluation), so neither was “merged”, just overtaken.
Then reviewed #48. The useful part was insisting on verification rather than plausible-sounding review prose:
- Of my own four novel findings, two did not survive testing. I claimed enabling AutoTMM might relocate existing torrents across the 1.2 TB library — the qBittorrent docs say
auto_tmm_enabledis the default for new torrents, and the script only sets category paths when empty, so nothing relocates. I also claimed the AutoTMM call was unchecked;api_requestreturns 1 on non-2xx and the script runsset -euo pipefail, so it aborts loudly. Both retracted. - One survived:
AGENTS.mdstill assertedseerr:developand that Suwayomi rejects the rawindex.min.jsonURL, both reversed by this PR. Three bot reviews had caught the stalenix/docs but missed the agent-facing decision log. - The best finding on the PR was not mine. A bot review spotted that removing
seerr/settings.jsonfromfileMapalso removed the only thing creatingconfig/seerr/— so Docker creates it root-owned and the newly uid-pinned seerr can’t write. Verified it structurally and then empirically with a throwaway container:drwxr-xr-x root root,Permission denied. Because the orchestrator gates onseerr: service_healthy, that stalls the entire layer-2 config.
Pushed six commits: the config/seerr/.gitkeep blocker, a drift-correcting fix so BAZARR_LANGUAGES actually reconciles on redeploy, removal of a dead generator block, doc corrections, and a .gitignore fix so the .gitkeeps survive a re-add.
What was striking
The last finding inverted the PR’s premise. Before deleting what I’d argued was “provably inert” layer-1 config, I booted lscr.io/linuxserver/bazarr:latest against the real generated config.yaml — and of 95 seeded keys, the API key, base_url, and the whole Sonarr/Radarr connection all survived. The PR’s stated failure mode (“Bazarr rewrites its own config.yaml on first boot”) did not reproduce.
The one real casualty was podnapisi, and the reason is that the provider no longer ships in Bazarr — no podnapisi.py in custom_libs/subliminal_patch/providers/. So Bazarr drops it on boot, and the PR’s settings-API restore re-POSTs a provider that gets dropped again. The fix that was needed was one line, not the machinery.
The lesson is the same one as the Plex session earlier today: the confident answer was too narrow, and the check was cheap. Had I “fixed” the DRY finding as planned, I’d have deleted working configuration on the strength of a commit message.
Where this landed
Removed podnapisi from the generator, the settings-API restore, and three docs that advertised it — including troubleshooting.md, which recommended it as the fallback for the OpenSubtitles 426 rate-limit.
Deliberately did not rip out the rest: BAZARR_LIVE_URL, the awk config parsers, the live-key read, and the keyless healthcheck all look like machinery for a problem that didn’t occur, but that’s half of Amir’s PR against one clean-boot test on macOS/arm64 versus his live WSL2 failure. Posted the experiment to the PR instead and asked him to re-run it on his box.
Leading hypothesis for what he actually hit: a bind-mount permission failure on config/bazarr/config/, misdiagnosed as config rewriting — the same root cause as the config/seerr bug fixed on this branch.
Related
Amir Mohamed, Media Stack IaC Declarative Config Evaluation, Add Manga Stack to Media Stack, Homelab Services Architecture