v4.1.38 — a KEPUB the server cannot repair no longer rescans your whole library on every boot
LatestOut-of-band release — v4.1.37 introduced a crash loop, so this one does not wait for the daily train.
If you are on v4.1.37 and your container keeps restarting, this is the release you want.
Fixed
A KEPUB the server cannot repair no longer makes every restart scan the whole library again.
v4.1.37 introduced a startup pass that repairs KEPUB files with a packaging defect. Its inspection step returns "I cannot read this" for certain books — an older kepubify file missing kobo.js, or a package larger than the repair safety limit — and the task treated that as the whole job failing. It then refused to record itself as done, so the complete library scan started again on every single container start, forever. The symptoms were high CPU, database is locked and Cannot operate on a closed database errors, and a container that kept crashing. Deleting every .kepub was the only workaround.
A book the repair pass explicitly refuses is now recorded once, reported as unsupported rather than failed, and skipped on later starts — so the scan finishes and does not come back. A genuine read error, including a short read on a network share, is still retried rather than permanently skipping a book that was only briefly unreadable. The task list now reads N clean, N repaired, N unsupported, N failed.
Two things this deliberately does not do: the refused books are still not repaired (nothing the server rewrites was widened), and they are never re-read or hashed — which matters specifically for the over-size refusal.
Reported by @iroQuai in #1696, with logs specific enough to reproduce from directly.
Also fixed during review of the above: the code that saved the "repair completed" marker went through a helper that swallows a locked-database error and quietly restores the old value — so on an instance already suffering lock contention, the repair could finish, report success, and still rescan on the next boot. It now verifies the marker persisted and reports a failure if it did not.
Added
A Kobo two-way annotation sync opt-in appears in settings, switched off, and deliberately does nothing yet. Work has started on letting the server hold the authoritative copy of your Kobo highlights. That is a replace protocol — whatever the server answers becomes the reader's entire set for that book — so it is being built in stages behind two opt-ins that both default to off. This release adds only the storage and the controls. Nothing your Kobo receives changes, whether the opt-ins are on or off.
Known limitation
The repair pass's cheap inspection reads only container.xml and the package document, while the full repair reads every document in the book. A book that passes inspection but that the repairer then declines while loading it fully still ends up in the old rescan loop. It is pre-existing, it is tracked, and its fix is a design change rather than a patch — so it is not in this release. If you still see a rescan after updating, the task list will show a non-zero failed count with 0 unsupported; say so on #1696.
Upgrading
docker pull ghcr.io/new-usemame/calibre-web-nextgen:v4.1.38
Patch release — no breaking config, database, or API changes. One additive app.db migration adds four nullable columns to the KEPUB repair table; no metadata.db change.