Peoples and PeopleBaseItemMap are never written #12

Closed
opened 2026-08-02 14:27:23 +02:00 by Claude · 1 comment
Collaborator

Peoples 0 against upstream's 357; PeopleBaseItemMap 0 against 9 151.

Upstream populates both from container tags with every remote provider
disabled. /Persons answers 200 with an empty list as a result.


Found by scanning /mnt/media (285 movies, 289 shows, 74 music artists —
~13 000 media files on a CIFS mount) with both this server and upstream
Jellyfin at the pinned commit, remote metadata and image fetchers disabled on
upstream so both were reading files only. Upstream was given the same mount
path so MD5(UTF-16LE(path)) agrees and rows compare directly.

`Peoples` 0 against upstream's 357; `PeopleBaseItemMap` 0 against 9 151. Upstream populates both from container tags with every remote provider disabled. `/Persons` answers `200` with an empty list as a result. --- Found by scanning `/mnt/media` (285 movies, 289 shows, 74 music artists — ~13 000 media files on a CIFS mount) with both this server and upstream Jellyfin at the pinned commit, remote metadata and image fetchers disabled on upstream so both were reading files only. Upstream was given the same mount path so `MD5(UTF-16LE(path))` agrees and rows compare directly.
Author
Collaborator

Fixed in d822cde, fb611a4, 3940e74 and 30a7e26.

Verified against the real library: every billing upstream files on a track,
this server now files too — 8425 links, none of them out of order, and none of
them ours alone
(was 0 rows).

upstream ours
PeopleBaseItemMap on a track 8425 8425
— of those, billed in a different place 0
links we file that upstream does not 0
PeopleBaseItemMap on an album 726 0
Peoples 363 302

By kind, on a track: Artist 4533, AlbumArtist 3660, Composer 232 — each
of them exactly upstream's.

The 726 that are left hang off MusicAlbum rows, which upstream bills from the
album's own artists. This server's albums carry none, which is #24 — the same
place the album-level provider ids went. The seven Peoples rows that go with
them are the album artists no track of theirs names.

Peoples itself is 363 against 302 for one more reason: upstream looks a person
up by a key SQLite folds and a key .NET folds, and the two disagree about a
letter no keyboard has — so MØL is filed 28 times over there and once here. A
client is shown one either way; only the table differs.


Three rounds of review, and the library found two more:

  • the columns are not the billing. A track's AlbumArtists column falls
    back to its artists where no tag named one, and both columns are split on
    delimiters a name may contain. Billing off them credited an album artist to
    1229 tracks that name none, and made two people of
    Craig Armstrong & Joseph Ray. The billing reads the tags: one name however
    it is punctuated, and two only where the file wrote the tag twice.
  • ALBUM ARTIST is not album_artist. No format defines the first, so the
    reader upstream bills from does not see it — but the column prefers it. A file
    carrying both is billed by the second, and 73 tracks here carry both.
  • a tag written twice was read as the first of the two. One mp3 here carries
    a broken album_artist frame ahead of a good one, and the album artist came
    out as eight characters of the frame's own name. Upstream copies each tag over
    whatever was under that key, so the last wins — 30a7e26 fixes the row as
    well as the billing.

A person's id is derived from their name and what they were credited as, the way
a value's is, so a rescan writes the row it wrote before. Upstream draws a fresh
guid for each, so that column is exempt from the database diff along with the
link that joins on it — as is ItemValuesMap.ItemValueId, which had been left
out when ItemValues was exempted.

Fixed in `d822cde`, `fb611a4`, `3940e74` and `30a7e26`. **Verified against the real library: every billing upstream files on a track, this server now files too — 8425 links, none of them out of order, and none of them ours alone** (was 0 rows). | | upstream | ours | |---|---|---| | `PeopleBaseItemMap` on a track | 8425 | **8425** | | — of those, billed in a different place | | 0 | | links we file that upstream does not | | 0 | | `PeopleBaseItemMap` on an album | 726 | 0 | | `Peoples` | 363 | 302 | By kind, on a track: `Artist` 4533, `AlbumArtist` 3660, `Composer` 232 — each of them exactly upstream's. The 726 that are left hang off `MusicAlbum` rows, which upstream bills from the album's own artists. This server's albums carry none, which is #24 — the same place the album-level provider ids went. The seven `Peoples` rows that go with them are the album artists no track of theirs names. `Peoples` itself is 363 against 302 for one more reason: upstream looks a person up by a key `SQLite` folds and a key `.NET` folds, and the two disagree about a letter no keyboard has — so `MØL` is filed 28 times over there and once here. A client is shown one either way; only the table differs. --- Three rounds of review, and the library found two more: - **the columns are not the billing.** A track's `AlbumArtists` column falls back to its artists where no tag named one, and both columns are split on delimiters a name may contain. Billing off them credited an album artist to 1229 tracks that name none, and made two people of `Craig Armstrong & Joseph Ray`. The billing reads the tags: one name however it is punctuated, and two only where the file wrote the tag twice. - **`ALBUM ARTIST` is not `album_artist`.** No format defines the first, so the reader upstream bills from does not see it — but the column prefers it. A file carrying both is billed by the second, and 73 tracks here carry both. - **a tag written twice was read as the first of the two.** One mp3 here carries a broken `album_artist` frame ahead of a good one, and the album artist came out as eight characters of the frame's own name. Upstream copies each tag over whatever was under that key, so the last wins — `30a7e26` fixes the row as well as the billing. A person's id is derived from their name and what they were credited as, the way a value's is, so a rescan writes the row it wrote before. Upstream draws a fresh guid for each, so that column is exempt from the database diff along with the link that joins on it — as is `ItemValuesMap.ItemValueId`, which had been left out when `ItemValues` was exempted.
Sign in to join this conversation.
No description provided.