github new-usemame/Calibre-Web-NextGen v4.0.70
v4.0.70 — fix Kobo sync retry loops and orphan magic shelves

latest releases: v4.0.172, v4.0.171, v4.0.170...
one month ago

What's new

docker pull ghcr.io/new-usemame/calibre-web-nextgen:v4.0.70

(or :latest)

Three Kobo sync bugs from a live MITM capture against a real Libra Colour FW 4.45.23684

If your Kobo has shelves that no longer exist on your CWNG instance, you may have noticed your device retrying DELETE on them every sync — burning bandwidth and spamming your server logs with 404s. Or you may have hit the symptom in #220: adding a book to a Kobo-sync shelf caused the device to loop syncing the same entitlement, 100+ times per minute. Or you may have flipped off the magic-shelf sync feature globally and noticed your device kept the old magic shelves forever.

All three turn out to share the same anti-pattern, and all three are fixed in this release.

B1 — ghost-shelf 404 retry loop. When the device pushed DELETE /v1/library/tags/<id> for a shelf CWNG no longer had (because it was deleted server-side, or was a magic shelf that no longer syncs), CWNG answered HTTP 404. The Kobo interprets 404 as transient and retries indefinitely — the wire capture caught 6+ retries per sync against two specific ghost-shelf IDs. The sibling reading-state handler at line ~989 has documented this exact pattern and uses redirect_or_proxy_request() unconditionally so the loop terminates. Both HandleTagUpdate and HandleTagRemoveItem now do the same, regardless of config_kobo_proxy.

B2 — infinite sync loop after adding a book to a Kobo-sync shelf (closes #220). The sync filter matches a book when EITHER Books.last_modified OR BookShelf.date_added is past the cursor, but the cursor advance only ever read Books.last_modified. A book added to a Kobo-sync shelf after its own last_modified re-matched every sync forever — wire-confirmed at 112 sync requests in 60 seconds, ~436 KB/min wasted bandwidth, identical 4118-byte responses each cycle, with x-kobo-sync: continue as the trap signal that told the device to come back immediately. The cursor now folds BookShelf.date_added into new_books_last_modified so the loop terminates after one cycle.

B4 — magic shelves linger on the device after config_kobo_sync_magic_shelves is flipped off. The DeletedTag emission block was wholly nested under the global flag. When admin turned magic-shelf sync off, no tombstones were ever emitted, leaving orphans on previously-synced devices (and triggering B1's retry loop on top). DeletedTag now fires regardless of the global flag — when on, for per-shelf kobo_sync=False; when off, for all the user's magic shelves so the device can clean up.

Not in this release: B3 (book deleted from library lingers on device)

The fourth bug from the cluster — books deleted from CWNG persisting on the device — shares the same root cause but needs a schema migration to capture the book UUID before delete. It's deferred to a follow-up review-tier PR. Design doc lives at notes/B3-kobo-deleted-book-tombstone-DESIGN.md in the repo.

Credits

Thanks @Hoite for the detailed #220 report — the symptom there is exactly the wire-captured B2 loop.

Full diff

v4.0.69...v4.0.70

Don't miss a new Calibre-Web-NextGen release

NewReleases is sending notifications on new releases.