fix(jellyfin): refuse a library that indexes files but fetches nothing
The Movies library had indexed 2,571 films and had never asked a provider
for a single one: no TMDb id, no plot, no rating, no poster. Nothing was
broken in the provider chain — the plugin is core in 12.4 and active, its
key is set, image.tmdb.org answers the container — and nothing was broken
in the write path: the overlay view has been read-write since the 2026-10-31
cutover, and movie.nfo lands on the NVMe upper layer today.
The state was two settings in the per-library option file,
config/root/default/<Library>/options.xml (Jellyfin 12 renamed it from
library.xml; the database stores none of these options, so a census that
greps for the old name and then queries the DB concludes nothing is
configured and goes hunting elsewhere):
<EnableInternetProviders>false</EnableInternetProviders>
<TypeOptions><ImageFetchers /> (empty, beside a populated
<MetadataFetchers> and a fully
populated <ImageFetcherOrder>)
With the internet switch off every refresh answers 204, stores nothing and
logs nothing, so the item count reads like a healthy scan — this passed the
deploy health gate, the Playwright suite and three agent audits. Order is
not enablement: the fetcher ORDER stays populated while the ENABLED set sits
empty, and the populated metadata list beside it makes the library look well.
verify now audits every library's options.xml and fails with `SILENT INDEX
<Library>: <what>` on providers-off or on a type whose image fetchers are
empty while its metadata fetchers are named; an options.xml that never
carried the switch (BoxSets, written before the property existed) is the
vendor default and stays accepted.
Vault: the page claimed artwork is a sidecar like movie.nfo. It is not — no
image saver is bound for any library, so art goes to the internal store and
Plex never reads it. The claim is corrected, and the RemoteImages diagnostic
that separates a provider fault from a library fault is written down with
the 12.x API shape traps (Items needs UserId; MetadataRefreshMode has no
Full/ValidationFailure, ReplaceAllMetadata=true is what re-runs providers).
This commit is contained in:
1 parent
7cf388367e
commit
52600b28ab
3 files changed
+187
-5
No files matched your search
@@ -46,10 +46,14 @@ sees is the [[Media Metadata View]] overlay, live since the 2026-10-31 cutover:
|
||||
`/var/lib/media-meta/view:/data`, read-write.
|
||||
|
||||
`Local metadata` — save metadata to media folders — is enabled, and it is the
|
||||
reason the view exists: `movie.nfo`, `tvshow.nfo`, `episode.nfo` and artwork
|
||||
written once on the NVMe upper layer are files [[Plex]] can read too — and since
|
||||
the 2026-10-31 cutover that is what happens: Jellyfin is the fleet's only
|
||||
metadata writer, and every sidecar it saves is an SSD byte the array never sees.
|
||||
reason the view exists: `movie.nfo`, `tvshow.nfo` and `episode.nfo` written once
|
||||
on the NVMe upper layer are files [[Plex]] can read too — and since the
|
||||
2026-10-31 cutover that is what happens: Jellyfin is the fleet's only metadata
|
||||
writer, and every sidecar it saves is an SSD byte the array never sees.
|
||||
**Artwork is not one of those sidecars.** No image saver is bound for any
|
||||
library, so posters and fanart go to the internal store
|
||||
(`config/metadata/library/<xx>/<item-id>/poster.jpg`), which [[Plex]] never
|
||||
reads — movie art has never existed beside the media on either layer.
|
||||
|
||||
**Library coverage is the first thing to check when a title is missing.** The
|
||||
four libraries are `movies → /data/Movies`, `tvshows → /data/TVShows`,
|
||||
@@ -66,6 +70,32 @@ instead of the view — always a fault on this host since the 2026-10-31 cutover
|
||||
`scripts/media-view.sh status` says which: the quadlet drifted back to the raw
|
||||
array, or the mount died.
|
||||
|
||||
**`EnableInternetProviders` false turns a library into a silent file index.**
|
||||
Every refresh answers `204`, stores nothing and logs nothing — no provider ids,
|
||||
no plot, no rating, no art — while the item count reads like a healthy scan. The
|
||||
switch lives in `config/root/default/<Library>/options.xml`, Jellyfin 12's name
|
||||
for the per-library option file: grepping for the old `library.xml` concludes "no
|
||||
per-library options exist", and the database holds none, so the trail dies there.
|
||||
Two more traps in the same file: `TypeOptions/ImageFetchers` is the *enabled* set,
|
||||
so an empty `<ImageFetchers />` switches art off while `ImageFetcherOrder` stays
|
||||
fully populated — order is not enablement — and the populated `<MetadataFetchers>`
|
||||
built next to it makes the library look healthy.
|
||||
|
||||
**`RemoteImages` is the call that separates a provider fault from a library
|
||||
fault.** `GET /Items/{id}/RemoteImages?Type=Primary` returns the provider's real
|
||||
poster list even with every automatic pass switched off — plugin, key and CDN all
|
||||
proven by that one response — so a refresh that stores nothing beside it is a
|
||||
library-switch problem, never a provider problem. It is also the delivery door:
|
||||
`POST /Items/{id}/RemoteImages/Download` saves the chosen image to the internal
|
||||
store on a build where the automatic image pass will not run at all.
|
||||
|
||||
**API shape on 12.x:** `/Items` and `/Items/{id}` need `UserId` when
|
||||
authenticated by API key — without it the answer is `400 Error processing
|
||||
request`, which reads exactly like an authentication failure. `MetadataRefreshMode`
|
||||
accepts `Default` (and `Realtime`) only; `Full` and `ValidationFailure` are
|
||||
rejected outright, and what forces the providers to re-run is
|
||||
`ReplaceAllMetadata=true`.
|
||||
|
||||
## Ports & access
|
||||
|
||||
| Port | Proto | Purpose |
|
||||
|
||||
Reference in new issue
Block a user