docs(jellyfin): name the library doors, the watcher, and the phantom records

Measured 2026-11-02 against the live server. The per-library posture goes on the
page because two libraries are silent file indexes right now: Shows and Music
carry EnableInternetProviders=false, so a refresh on either answers 204 and
stores nothing — any metadata or artwork work there starts by flipping the
switch, not by scanning. Movies additionally has EnableRealtimeMonitor=false, so
a folder moved into /data/Movies stays invisible until a recursive refresh names
it; "Jellyfin does not see the file" is the designed answer, not a fault.

Recorded with it: the option door on 12.x is POST
/Library/VirtualFolders/LibraryOptions (GET answers 405 — that is how the route
is found) while the 10.x /Update and /Refresh routes answer 404 outright, and
the VirtualFolders DTO is PascalCase, so a census written against the old
camelCase keys reads None and misreports a healthy library as unconfigured.
A library record can also be a phantom: a 2026-11-01 capture carried Shows2,
Shows3 and Music2 with empty Locations while only four libraries existed, so the
live set is the entries with non-empty Locations and never the record count.
This commit is contained in:
Frank committed 2026-11-02 02:12:19 -08:00
1 parent 51ed5c0b2a
commit 2e69215920
1 file changed
+34
@@ -81,6 +81,34 @@ so an empty `<ImageFetchers />` switches art off while `ImageFetcherOrder` stays
fully populated — order is not enablement — and the populated `<MetadataFetchers>` fully populated — order is not enablement — and the populated `<MetadataFetchers>`
built next to it makes the library look healthy. built next to it makes the library look healthy.
**Live posture, measured 2026-11-02** from `GET /Library/VirtualFolders`. The DTO is
PascalCase — `Name`, `CollectionType`, `Locations`, `ItemId`, `RefreshStatus` — and a
census written against the 10.x camelCase keys reads `None` for everything, which
looks exactly like an unconfigured library.
| Library | `CollectionType` | `EnableInternetProviders` | `EnableRealtimeMonitor` |
|---|---|---|---|
| `Movies` | movies | true (fixed 2026-11-02) | **false** |
| `Shows` | tvshows | **false** | true |
| `Music` | music | **false** | true |
| `Collections` | boxsets | **false** | false |
`Shows` and `Music` are silent file indexes in the sense above: a refresh answers
`204`, stores nothing, logs nothing. Any metadata or artwork work on either one
starts by flipping the switch, never by firing a scan.
**The per-library option door on 12.x is `POST /Library/VirtualFolders/LibraryOptions`**
— `GET` there answers `405`, which is how the route announces itself. The 10.x doors
are gone: `/Library/VirtualFolders/Update` and `/Library/VirtualFolders/Refresh`
answer `404` on this build, so every recipe naming them fails outright.
**A library record can be a phantom.** A per-library option capture taken 2026-11-01
carried seven entries — `Shows2`, `Shows3`, `Music2` among them, each with
`Locations: []` and a live-looking `ItemId` — while `GET /Library/VirtualFolders` the
same day listed four. A numeric suffix on a library name is what a deleted and
recreated library leaves behind. The live set is the entries whose `Locations` are
non-empty; count those and never the records.
**`RemoteImages` is the call that separates a provider fault from a library **`RemoteImages` is the call that separates a provider fault from a library
fault.** `GET /Items/{id}/RemoteImages?Type=Primary` returns the provider's real 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 poster list even with every automatic pass switched off — plugin, key and CDN all
@@ -263,6 +291,12 @@ folders created on the host stay invisible to it. The move is
`GET /Library/VirtualFolders` — its field is `ItemId`, not `Id` — and that same `GET /Library/VirtualFolders` — its field is `ItemId`, not `Id` — and that same
record's `RefreshStatus` is the progress read. record's `RefreshStatus` is the progress read.
**`Movies` has no watcher at all.** `EnableRealtimeMonitor` is per library (table in
*Data layout*) and it is false for `Movies` and `Collections`. Nothing notices a
folder created under `/data/Movies`: it stays invisible until a recursive refresh
names it. So every pass that writes into a library ends by firing one, and "Jellyfin
does not see the file I just moved in" is the designed answer, not a fault to chase.
## See Also ## See Also
- [[Plex]] — co-resident media server on the same volume - [[Plex]] — co-resident media server on the same volume