A first scan leaves every TV series unidentified, and a series' own row is never described #176

Closed
opened 2026-08-22 17:01:11 +02:00 by Claude · 1 comment
Collaborator

Found by clicking through the throwaway instance in TESTCONTAINER/ — a real
CIFS library of 284 films, 294 series, 717 seasons, 7,975 episodes, every
library fetch_metadata = true, scanned by the image built at 33a1bdd.

What it looks like

Every card in the Shows library is a placeholder. A series page has no poster,
no backdrop, no cast, no Status and no network. Recently Added in Shows on
the home screen is five blank season tiles.

What the rows say

  • 0 of 294 Series rows and 0 of 717 Season rows have a single row in
    BaseItemImageInfos. Films are 284/284 and episodes 7,971/7,975.
  • Every series carries exactly one provider id, Imdb, and never Tmdb.
  • 7,065 of 7,975 episodes are named after their series rather than after the
    title the filename spells — Star Trek - Strange New Worlds (2022) - S01E01 - Strange New Worlds [WEBDL-1080p]….mkv is filed as Star Trek - Strange New Worlds.

The ids are the tell. Imdb alone and an overview beside it is exactly what
Omdb::identify returns from its title search, so these rows were described by
the second database and never by the first.

Why

Tmdb::identify_series (crates/ephyra-app/src/metadata/tmdb/tv.rs:251) starts
from an id the row already carries — Tmdb, then Imdb, then Tvdb — and
answers None for a series carrying none of the three. There is no /search/tv
request anywhere in the crate; the only two searches are
/search/collection and /search/person.

On a first pass over a folder named Ted Lasso (2020) there is no id to start
from. The Imdb id the row ends up with is written by that same pass, after
identification has already given up — so the first scan of a TV library
identifies nothing, and nothing below a series is identified either, because a
season and an episode both read the series' resolved id.

A forced per-item refresh is the proof. Replace all metadata on Ted Lasso,
whose row by then carries the Imdb id the first pass wrote: its four seasons
come back with Tmdb and Tvdb ids and real posters, and its episodes come
back with real titles.

The series' own row is a second hole

That refresh left the series itself unchanged — still no Tmdb id, still no
image — while the seasons under it succeeded. from_tmdb and fetch_pictures
ask about a Kind::Series with asked_about(remote, item), the ids on the row,
rather than with the lookup identified_series just resolved
(crates/ephyra-app/src/scan/run/remote.rs:117 and :239). series_id() reads
Tmdb off what it is handed, finds none, and both the fields and the artwork
come back empty on the very pass where everything below the series works.

Upstream

TmdbSeriesProvider.GetMetadata falls back to SearchSeriesAsync(cleanedName, …, info.Year ?? parsedName.Year ?? 0) —
upstream/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs:205. A
folder with no id in its name is identified on the first pass, and a scan of
this library would come back with posters.

Where to start

Two edges, and they are separable.

metadata/tmdb/tv.rs needs the name search identify_series currently has no
fallback to — TMDb's /search/tv?query=…&first_air_date_year=…, over the same
MetadataHttp port, matching what upstream's SearchSeriesAsync sends.

scan/run/remote.rs needs a Kind::Series to be asked about through the
identified lookup rather than through the row, so its own fields and pictures
land on the pass that resolved it.

How to know it is done

A scan of a TV library whose folders carry no ids leaves every series with a
Tmdb provider id and a poster on the first pass, episode titles are the ones
their filenames spell, and the fixture's series exercise both edges — the
scan_enriched answer key should disagree today.

House rules

Tests run under cargo nextest; upstream's source is the checkout in
upstream/ at the pin. Generated artifacts are regenerated, never edited.

Found by clicking through the throwaway instance in `TESTCONTAINER/` — a real CIFS library of 284 films, 294 series, 717 seasons, 7,975 episodes, every library `fetch_metadata = true`, scanned by the image built at `33a1bdd`. ## What it looks like Every card in the Shows library is a placeholder. A series page has no poster, no backdrop, no cast, no `Status` and no network. `Recently Added in Shows` on the home screen is five blank season tiles. ## What the rows say - **0 of 294** `Series` rows and **0 of 717** `Season` rows have a single row in `BaseItemImageInfos`. Films are 284/284 and episodes 7,971/7,975. - Every series carries exactly one provider id, `Imdb`, and never `Tmdb`. - **7,065 of 7,975** episodes are named after their series rather than after the title the filename spells — `Star Trek - Strange New Worlds (2022) - S01E01 - Strange New Worlds [WEBDL-1080p]….mkv` is filed as `Star Trek - Strange New Worlds`. The ids are the tell. `Imdb` alone and an overview beside it is exactly what `Omdb::identify` returns from its title search, so these rows were described by the second database and never by the first. ## Why `Tmdb::identify_series` (`crates/ephyra-app/src/metadata/tmdb/tv.rs:251`) starts from an id the row already carries — `Tmdb`, then `Imdb`, then `Tvdb` — and answers `None` for a series carrying none of the three. There is no `/search/tv` request anywhere in the crate; the only two searches are `/search/collection` and `/search/person`. On a first pass over a folder named `Ted Lasso (2020)` there is no id to start from. The `Imdb` id the row ends up with is written by *that same pass*, after identification has already given up — so the first scan of a TV library identifies nothing, and nothing below a series is identified either, because a season and an episode both read the series' resolved id. A forced per-item refresh is the proof. `Replace all metadata` on *Ted Lasso*, whose row by then carries the `Imdb` id the first pass wrote: its four seasons come back with `Tmdb` and `Tvdb` ids and real posters, and its episodes come back with real titles. ## The series' own row is a second hole That refresh left the series itself unchanged — still no `Tmdb` id, still no image — while the seasons under it succeeded. `from_tmdb` and `fetch_pictures` ask about a `Kind::Series` with `asked_about(remote, item)`, the ids on the row, rather than with the lookup `identified_series` just resolved (`crates/ephyra-app/src/scan/run/remote.rs:117` and `:239`). `series_id()` reads `Tmdb` off what it is handed, finds none, and both the fields and the artwork come back empty on the very pass where everything below the series works. ## Upstream `TmdbSeriesProvider.GetMetadata` falls back to `SearchSeriesAsync(cleanedName, …, info.Year ?? parsedName.Year ?? 0)` — `upstream/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs:205`. A folder with no id in its name is identified on the first pass, and a scan of this library would come back with posters. ## Where to start Two edges, and they are separable. `metadata/tmdb/tv.rs` needs the name search `identify_series` currently has no fallback to — TMDb's `/search/tv?query=…&first_air_date_year=…`, over the same `MetadataHttp` port, matching what upstream's `SearchSeriesAsync` sends. `scan/run/remote.rs` needs a `Kind::Series` to be asked about through the identified lookup rather than through the row, so its own fields and pictures land on the pass that resolved it. ## How to know it is done A scan of a TV library whose folders carry no ids leaves every series with a `Tmdb` provider id and a poster on the first pass, episode titles are the ones their filenames spell, and the fixture's series exercise both edges — the `scan_enriched` answer key should disagree today. ### House rules Tests run under `cargo nextest`; upstream's source is the checkout in `upstream/` **at the pin**. Generated artifacts are regenerated, never edited.
Author
Collaborator

Fixed in 28bdd65, with the review's findings in 113caba.

Both edges are closed. identify_series falls back to /search/tv on the
name and the year, which is what upstream does and what identifies a library
whose folders carry no ids; and a series is asked about through the lookup the
pass resolved rather than through the ids on its row, so its own fields and
pictures land on the pass that identified it.

Verified on the throwaway instance's real library — the same 294 series this
was measured on. Before: 0 carried a Tmdb id and 0 had a single row
in BaseItemImageInfos. After refreshing three of them on the fixed build:

Name             Tmdb     pictures
11.22.63         64464    4
2 Broke Girls    39340    4
3 Body Problem   108545   4

Four pictures each — poster, backdrop, logo and thumb — and the library grid
draws them, with the 2011 - 2017 and 2024 - Present ranges that only come
from a series the database answered for.

One thing the review caught, and it is the reason a review is worth the round
trip: asking through the pass' lookup alone threw away the ids a tvshow.nfo
carries. That file is read into the row before any database is asked, and an id
in it is the operator saying which series this is — a folder called
The Office with a tmdbid would otherwise have been described as whichever
series a search answered with first, and stuck that way, because the next pass
would find it already resolved. What the item names now wins and the pass fills
only what it leaves empty.

Fixed in `28bdd65`, with the review's findings in `113caba`. Both edges are closed. `identify_series` falls back to `/search/tv` on the name and the year, which is what upstream does and what identifies a library whose folders carry no ids; and a series is asked about through the lookup the pass resolved rather than through the ids on its row, so its own fields and pictures land on the pass that identified it. Verified on the throwaway instance's real library — the same 294 series this was measured on. Before: **0** carried a `Tmdb` id and **0** had a single row in `BaseItemImageInfos`. After refreshing three of them on the fixed build: ``` Name Tmdb pictures 11.22.63 64464 4 2 Broke Girls 39340 4 3 Body Problem 108545 4 ``` Four pictures each — poster, backdrop, logo and thumb — and the library grid draws them, with the `2011 - 2017` and `2024 - Present` ranges that only come from a series the database answered for. One thing the review caught, and it is the reason a review is worth the round trip: asking through the pass' lookup alone threw away the ids a `tvshow.nfo` carries. That file is read into the row before any database is asked, and an id in it is the operator saying which series this is — a folder called `The Office` with a `tmdbid` would otherwise have been described as whichever series a search answered with first, and stuck that way, because the next pass would find it already resolved. What the item names now wins and the pass fills only what it leaves empty.
Sign in to join this conversation.
No description provided.