The startup scan deletes box-set rows and logs that it removed nothing #130

Closed
opened 2026-08-14 02:15:31 +02:00 by Claude · 0 comments
Collaborator

Found while reviewing #111, on a copy of the reference database carrying 87 rows.

Starting this server against that database deletes the two BoxSet rows, logging:

"a library of a kind this server does not scan","kind":"boxsets"
removed: 0

Two things wrong at once. The rows go — a collection an operator made through /Collections, or that upstream wrote, is gone after one start of this server. And the log says removed: 0 while removing two, so nothing about the event is discoverable afterwards.

M9 built /Collections and the routes under it, and settled that a collection's directory carries upstream's [boxset] suffix; a scan that then deletes the row on the next boot undoes that. The sweep is the one M9's review already narrowed once — "a CollectionFolder is not only a library" — and this is the same sweep reaching a different row it should not.

Where to start

The reconciliation sweep in crates/jellyfin-server/src/main.rs — the pass that takes away libraries the configuration no longer names. boxsets is a kind this server refuses to scan (M9 records that deliberately: taking homevideos or books would write a definition upstream reads and rows we never file). Refusing to scan a kind is not the same as being allowed to delete rows of that kind, and that is the conflation to unpick.

The removed: 0 half is its own bug and probably the easier one to fix first — a count that does not count what the code just did will hide the next instance of this too.

How to know it is done

A database carrying box sets is unchanged by a start of this server: diff-db reports nothing on BaseItems after a boot that scans nothing. And the log line reports what actually went.

This blocks measuring anything about box sets against a pair, which is how it was found — #111's review had to file a box set under the user root by hand because ours kept eating it.

House rules

Tests run under cargo nextest; upstream's source is the checkout in upstream/ at the pin; generated files are regenerated rather than edited; comments say what the code does, not how it got there. Anything needing a write wants its own container from the pinned image over a sqlite3 .backup copy of reference/var/config/data/jellyfin.db, on ports of its own — the shared reference on :8096 is read-only.

Found while reviewing #111, on a copy of the reference database carrying 87 rows. Starting this server against that database **deletes the two `BoxSet` rows**, logging: ``` "a library of a kind this server does not scan","kind":"boxsets" removed: 0 ``` Two things wrong at once. The rows go — a collection an operator made through `/Collections`, or that upstream wrote, is gone after one start of this server. And the log says `removed: 0` while removing two, so nothing about the event is discoverable afterwards. M9 built `/Collections` and the routes under it, and settled that a collection's directory carries upstream's ` [boxset]` suffix; a scan that then deletes the row on the next boot undoes that. The sweep is the one M9's review already narrowed once — *"a `CollectionFolder` is not only a library"* — and this is the same sweep reaching a different row it should not. ## Where to start The reconciliation sweep in `crates/jellyfin-server/src/main.rs` — the pass that takes away libraries the configuration no longer names. `boxsets` is a kind this server refuses to *scan* (M9 records that deliberately: taking `homevideos` or `books` would write a definition upstream reads and rows we never file). Refusing to scan a kind is not the same as being allowed to delete rows of that kind, and that is the conflation to unpick. The `removed: 0` half is its own bug and probably the easier one to fix first — a count that does not count what the code just did will hide the next instance of this too. ## How to know it is done A database carrying box sets is unchanged by a start of this server: `diff-db` reports nothing on `BaseItems` after a boot that scans nothing. And the log line reports what actually went. This blocks measuring anything about box sets against a pair, which is how it was found — #111's review had to file a box set under the user root by hand because ours kept eating it. ### House rules Tests run under `cargo nextest`; upstream's source is the checkout in `upstream/` **at the pin**; generated files are regenerated rather than edited; comments say what the code does, not how it got there. Anything needing a write wants its own container from the pinned image over a `sqlite3 .backup` copy of `reference/var/config/data/jellyfin.db`, on ports of its own — the shared reference on `:8096` is read-only.
alex closed this issue 2026-08-16 11:18:36 +02:00
Sign in to join this conversation.
No description provided.