Skip to content

feat(container): update image ghcr.io/vavallee/bindery ( v1.33.2 ➔ v1.34.0 ) - #2625

Open
nerdz-bot[bot] wants to merge 1 commit into
mainfrom
renovate/ghcr.io-vavallee-bindery-1.x
Open

feat(container): update image ghcr.io/vavallee/bindery ( v1.33.2 ➔ v1.34.0 )#2625
nerdz-bot[bot] wants to merge 1 commit into
mainfrom
renovate/ghcr.io-vavallee-bindery-1.x

Conversation

@nerdz-bot

@nerdz-bot nerdz-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Update Change
ghcr.io/vavallee/bindery minor v1.33.2v1.34.0

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Release Notes

vavallee/bindery (ghcr.io/vavallee/bindery)

v1.34.0

Compare Source

A tidier interface, the second half of the audit, and the two things Discord asked for.

Twenty nine entries below, from thirty seven merged pull requests. The visible
change is the first pass at decluttering the interface: the Authors and Books
filter rows collapse into two menus, the rare per row actions move into an
overflow menu, and the app stops flashing light before it turns dark. Nothing
was taken away to achieve it; every option that was on those pill rows is still
there, one click further in, and the Filters button says how many are applied.

The rest is mostly the remainder of the tree scan that produced v1.33.4: four
more security fixes, a set of hot paths that were redoing work on every call,
and two controls that had never done anything being taken out of the interface
rather than left there promising behaviour that did not exist. The two features
both came from reports: a daily query cap for private trackers, and a log line
at the end of every automatic search so a silent sweep can be told apart from
one that never ran.

Two removals change what the API accepts. If you drive Bindery from a script,
read the Removed section before upgrading.

Added
  • Per-indexer daily query limit (#​2312). Set a cap on Settings → Indexers and Bindery stops searching that indexer once it has been sent that many requests in a rolling 24 hours, rather than finding out the hard way when the tracker starts refusing. This is for private trackers with a daily API allowance: one scheduled sweep over a large library searches every wanted book against every indexer back to back, and on a big enough library that single burst could spend a whole day's allowance and lock the account out for everything else pointed at the same tracker. Raising the search interval never helped, because it changes how often the burst happens and not how big one burst is. The unit is requests rather than books, since one book costs between one and eight depending on how far the search has to fall back, and the Indexers tab shows how much of the limit is spent. Leave it blank for no limit, which is what every existing indexer gets. The count survives a restart, a capped indexer says so in the interactive search panel instead of just going quiet, and the Test button is exempt so it still works when you are trying to work out why an indexer has gone quiet. Thanks to DrCrypt for the report.
  • Every automatic search now logs when it finishes (#​2154). A scheduled sweep, a bulk search or a series fill that found nothing used to log nothing at all, so "the search never ran" and "the search ran and found nothing" looked identical from the log. Each one now emits a single INFO line naming what started it, the book and format, how many indexers were queried, how many results came back, how many survived filtering, and how long it took. Thanks to SturmB for the report.
  • GET /series can be paginated (#​2345). The endpoint returned every series with every linked book, so the response grew with the whole catalogue and a large library paid for all of it on every load. Pass limit and/or offset and you get the same {items, total, limit, offset} envelope authors and books already use. Pass neither and the response stays the bare array it has always been, so nothing that consumes it today has to change.
  • A startup warning when a second account exists without tenancy (#​2358). BINDERY_ENFORCE_TENANCY is off by default, which is right for the single user install nearly everyone runs, but an operator who adds a second account through Settings had no way to learn that the two accounts share one library. Boot now logs one warning naming the variable when there is more than one user and the gate is off. It is a warning and not a gate: several accounts sharing a library is a supported setup, and changing the default would change what every existing multi user install does.
Changed
  • The Authors and Books filter rows are two menus instead of two rows of pills (#​2427). Every option survives, including the monitored filter and the choice it remembers between visits. An applied filter shows twice over, as a count on the Filters button and as a chip beside it that clears it, so nothing is hidden by being one click in. In table view the Sort menu is gone entirely, because the column headers already sort.
  • Refresh and Delete on an author row moved into a menu (#​2427). The monitored toggle stays where it was, since that is the control people actually use. The Discover card's own hand rolled menu now uses the same component and gains the keyboard handling it never had.
  • The setup checklist is a single strip (#​2427), naming the next step rather than boxing all five, and it stops showing once only one step is left.
  • The Authors rating column is hidden when nothing on the page has a rating (#​2427). Only OpenLibrary supplies author level ratings, so for a Hardcover or DNB sourced library it was a column of dashes. It still appears, and still sorts, wherever there is data.
  • Confirmation prompts are in app instead of browser dialogs (#​2359). Twenty two actions asked for confirmation through the browser's own dialog, which is unstyled, shows the origin in its title bar and cannot be translated. Four of them were hardcoded English that never reached the translation files at all. Every prompt now uses the in app dialog that book deletion already used, and the "I understand" checkbox is kept for the three that genuinely earn it rather than applied to all of them.
  • Queue, Wanted and the Logs tab stop polling while the tab is hidden (#​2360). Each polled every five seconds whether or not anyone was looking, so a queue left open in a background window made roughly 1,400 requests an hour with nothing to show for them. Polling now pauses when the tab goes away and does one immediate refresh when it comes back, so returning to the tab shows current data rather than data up to an interval stale.
  • Faster status reads, searches and wanted sweeps (#​2340, #​2341, #​2344, #​2346, #​2370, #​2407). Several hot paths were redoing work on every call. /system/status walked the entire image cache with one stat per file, which a 10,000 book library pays twice per cover, on a request the web UI makes from the root shell and four separate pages; the total is now memoised and adjusted by the exact delta after each cache write. The search filter compiled the same regular expression once per release and threw all but the first away, so a 500 result search compiled it 500 times. The wanted sweep reloaded the indexer list, the whole blocklist, the delay profiles and the preferred language once per book instead of once per sweep, and made seven separate status queries where one does. And the two startup backfills, which exist so that a change to the name normaliser re canonicalises existing rows, scanned the whole books and authors tables on every boot rather than only the boot after such a change. None of this changes what Bindery does, only how much it costs. Installs upgrading to this run each backfill once more and then settle.
  • File sizes render the same way everywhere (#​2350). Seven near copies of a byte formatter had drifted into four behaviours: the same release read "800 MB" on Search and History and "800.0 MB" on Queue and Wanted, Queue and Wanted showed "0 KB" for a zero size where the others showed nothing, and Settings → Root Folders had no unit ceiling, so a root folder with a petabyte or more free rendered "1.1 undefined". There is now one implementation. Two small things change on screen: exactly 1 GiB reads "1.0 GB" on Queue and Wanted rather than "1024.0 MB", and Search, History and the book detail page gain the decimal on MB.
  • Dependency updates (#​2176, #​2291). go-chi to v5.3.2 and modernc.org/sqlite to v1.57.0 on the Go side; i18next, react-i18next, react-router and the build and test tooling on the frontend. Every package keeps the licence it had.
Fixed
  • The app no longer flashes light before turning dark (#​2427). The theme class was applied from a React effect, which runs after the browser has already painted, so every route showed its light background for a frame first. It is now set before the first paint.
  • A mistyped or shared URL says so instead of showing an empty page (#​2427). Any path the app did not recognise rendered the header and nav around nothing at all. /settings/indexers also works now: it redirects to the tab it names.
  • A malformed id in a request no longer reports success for work that did not happen (#​2364). Five download client and root folder handlers parsed {id} and threw the error away, and a failed parse yields 0, so GET /downloadclient/abc looked up id 0 and answered "download client not found". A client that sent a bad id was told the resource does not exist. DELETE was worse: it ran the delete, the downloader eviction and the health drop against id 0 and then answered 204, so a typo in a script reported a successful delete that deleted nothing. All five now answer 400.
  • A redeploy no longer cuts off an author sync or a manual import mid flight (#​2371, #​2372). The author catalogue sync, the manual batch import and the reassign move ran on a context nothing cancelled or waited for, so a restart while one was running closed the database under it. The visible result was a half synced catalogue plus "database is closed" in the log, and on the import paths, files that had been moved with nothing in the database describing them. All three are now tracked and drained on shutdown the way a library scan already was.
  • Grab history records which indexer the release came from (#​2368). It was recording the wrong id, so the history for a grab pointed at an indexer that had not supplied it.
  • Re-binding a book to an OpenLibrary work now refreshes its release date and language (#​2306). An OpenLibrary work record carries neither field, so the single-work fetch behind Re-bind returned a book with no date and no language, and the stale values from the record being replaced survived the re-bind. The work is now enriched from the search index the way author sync already enriches every work it returns, so a re-bound book agrees with what a sync would have produced. The lookup is best-effort: if the search index is unreachable the re-bind still completes. Thanks to yarafie for the report.
  • Author aliases (#​2268). A latin-script author (a pen name, or a two-author collaboration credit) no longer has other real authors' OpenLibrary alternate names saved as its aliases. Alternate-name aliases are kept only for authors whose primary name is non-latin, which is the case they exist for. This is the root of the alias collapse edsilberberg reported in #​1684.
  • make test finishes again outside CI (#​2293). The race detector cannot get internal/api (1,000 tests) through a single timeout budget, so the target ran for half an hour and then died in a goroutine dump instead of a test result. make test now mirrors the gating CI check exactly, and the race detector moved to make test-race, which runs CI's same six shards. Thanks to magrhino for the report.
  • The rTorrent deletion test passes on macOS (#​2294). t.TempDir() there hands back /var/..., an alias for /private/var/..., and Bindery's delete guard refuses any path reached through a symlinked parent. The test now resolves its temp root the way the guard's own unit test already did. Production behaviour is unchanged. Thanks to magrhino for the report.
Removed
  • The "Downloading" book status filter, which always came back empty (#​2374). The downloading and downloaded book statuses were never written by anything in Bindery, so filtering the Books page or an author's catalogue by either returned no books no matter how many downloads were in flight. Both statuses are gone, along with the filter controls, the status legend entries and the API validation that accepted them. The Queue page remains the place to see downloads in progress. Any book row that picked up one of these values from a script or a third party client is rewritten to "wanted" on upgrade, and the API now rejects them.
  • Quality profile Cutoff and "Allow upgrading to a better format" (#​2373). Both controls are gone from Settings → Quality. Neither has ever done anything: no code path read either value, and Bindery has no upgrade re-grab sweep for a cutoff to gate, so an imported book is never searched again at any quality. The form was promising behaviour that did not exist, and nobody loses an upgrade they were getting. Your profiles are otherwise untouched: the stored values stay in the database and are still accepted over the API, so no migration runs and third party clients that send them keep working.
Security
  • Server filesystem paths in Settings are now admin only (#​2361). GET /setting and GET /setting/{key} handed the Calibre library and binary paths, the import drop folder, the CWA ingest path, the ABS and Calibre path remaps and the last library scan summary to every authenticated account, including OPDS only readers, while GET /system/storage has always been admin gated for revealing exactly that. Reads of those keys now match the admin gate that already guarded writing them; admins see the real values and Settings is unchanged for them.
  • The Readarr database import now validates the URLs it imports (#​2349). It was the one door into the indexer and download client tables that never ran the outbound URL check every other path uses, and its input is an uploaded database file rather than a form. A row pointing at a link local or internal address was created and then polled on a schedule, with whatever credentials came with it. Both loops now validate under the same policy the create and update handlers use, and a rejected row is named in the migration report with the reason instead of being silently created.
  • Prowlarr and OIDC discovery can no longer be redirected after the URL check (#​2353). Both validated the address up front and then dialled whatever the name resolved to a moment later, which is a window a DNS answer can be changed inside. Both now install the same dial time guard the image proxy and the notifier already use, and hand back the shared proxy transport untouched when an outbound proxy is configured.
  • The image proxy refuses SVG (#​2355). SVG is a scripting document, not an image, and it was being served same origin with the app. It is now rejected rather than proxied.
  • The container scan is meaningful again (#​2425). golang.org/x/crypto moves to v0.56.0, closing two high severity advisories that had made the image scan red on every pull request for long enough that people had started treating it as noise. Nothing in Bindery reaches the vulnerable code (it uses the library only for password hashing), so there is no exposure to act on, but a check that is always red hides the one that matters. The runtime image also moves off Debian 12, which reached end of life: the scanner's own data for an EOL release is incomplete, so a clean result there was not evidence of a clean image.

v1.33.4

Compare Source

A code audit, and the eight things it found that were wrong without anyone reporting them.

Nothing in this release came from a bug report. It is the output of a scan of the
whole tree, so the entries share a shape: each one is something Bindery did
quietly and confidently, on a path where nobody was watching. Three of them are
reachable by any account you have ever created, including a read-only reader
account. One of them destroys the database you asked it to protect.

Added
  • Safe author catalogue reconciliation (#​2208). Preview, select, and explicitly remove stale metadata-only Wanted rows after a provider or metadata-profile change, while imported and file-bearing books are protected from the sweep.
Fixed
  • Restoring a backup no longer reverts or corrupts the database it restored (#​2337). Restore copied the backup file over the live database while Bindery still had it open, and left the write-ahead log beside it untouched. SQLite validates those log frames against the log's own header rather than the database file, so everything written since the backup was replayed straight back over the restored data at the next checkpoint, and anything written between the restore and the restart went into the same log. The visible result was a restore that appeared to succeed and then quietly undid itself. Restore now validates the backup, stages it, and returns; the swap happens at the next start, before the database is opened, with the stale log files removed. This changes how restore behaves: the endpoint returns immediately but nothing takes effect until you restart Bindery. A staged file that turns out not to be a readable SQLite database is parked as .restore-failed and the live database is left alone. The staged file has no expiry, so if you change your mind before restarting, delete bindery.db.restore-pending.
  • A book that wants both formats no longer stops searching for the second one (#​2365). The wanted sweep skipped any book with a download in flight, counted per book rather than per format. Two states never end on their own: a hand-off to an external import tool, and a format held back waiting for its pair. A book parked in either therefore left its other format unsearched for as long as the download row existed, with nothing said. Under pair gating this was a deadlock, because the sibling the hold waits for could only ever arrive through the search the hold had just disabled. The sweep now tracks in-flight downloads per format. A book whose format cannot be determined from the release is still skipped whole, and a book monitored for a single format is skipped whenever it has any live download, because guessing there could only free the slot that is already downloading. After upgrading, books that have sat idle may start downloading their missing format; the searches are paced at the same rate as any other sweep.
  • The Hardcover series view no longer collapses a numbered series onto one volume (#​2343). Volume numbers were compared with a fuzzy title score that reads "Vol. 1" as a substring of "Vol. 13", so the two scored a perfect match. If your library had no recorded position for a book, which is normal after an Audiobookshelf or Calibre import, owning volume 13 showed volume 1 as present under volume 13's title, and left volume 13 in the missing list. Only numbers carrying an earlier number as a digit prefix collided, so 10 through 19 against 1, and 21 against 2. Volume numbers now veto the similarity score, the same way adding a book already did. A catalog entry can also no longer be claimed by two of your books at once. The view is rebuilt on every load, so it corrects itself as soon as you open it.
  • An Audiobookshelf item with no series sequence no longer binds to the wrong volume (#​2347). The same fuzzy comparison, on the import side. When the item carried no sequence number, every volume in the series was scored against its title at a threshold below the range sibling volumes actually score in, and the item was linked to whichever scored highest, which the substring rule usually made the longest number. Items with a sequence were never affected. Unlike the series view, this one does not heal on its own: volumes already linked to the wrong Hardcover entry stay linked to it after upgrading.
  • "Retry all failed" now retries the rows it says it will (#​2336). The button filtered on Import Failed alone while the retry endpoint behind it has always accepted Import Blocked too, so a queue full of blocked rows offered a button that did nothing. The queue's status labels, colours, and the failed and matchable sets are now derived from one table instead of four hand-maintained lists that had drifted apart. Note that the failed count does not drop when you press it: a retried row returns to Import Failed until the scanner runs again, and the signal to watch is the error text clearing.
  • The queue no longer shows a raw internal name for two of its states (#​2339). A download handed to an external import tool, or held waiting for its paired format, rendered as importExternal or importHeld in a grey chip with no explanation, which is exactly when a user most needs to know why a row is not moving. Both now have a label and a line saying what they are waiting for.
  • Six reads of a third-party response are no longer unbounded (#​2357). Replies from Prowlarr, qBittorrent, NZBGet, and an indexer's capability document were read into memory whole, with no ceiling, on a schedule and unattended. A misbehaving or hostile service could exhaust memory. The caps are set well above what a large install produces: the qBittorrent limit holds around 28,000 torrents, against 5,000 for the largest install anyone has reported. Reaching one now reports what happened instead of failing later as a truncated document.
Security
  • The OIDC discovery probe is now admin-only (#​2348). POST /auth/oidc/test-discovery was registered outside the admin group, so any authenticated account could point it at an address on your network and read the outcome. The four possible answers are distinguishable from each other, which turns the endpoint into a way to map internal hosts and ports from inside the Bindery container. The handler always believed it was admin-only; its own comment said so. Reachable by any account, including a reader account created only for OPDS.
  • The Google Books API key is no longer readable by every account (#​2351). The rule that keeps secrets out of the settings list matches names ending in .api_key or .api_token, and both spellings of this key match neither, so it was returned in full to anyone signed in. It is now write-only, like the Hardcover token. The field on Settings → API Keys now loads empty. Your key is still stored and still in use. Type a new one only if you want to replace it; the Save button beside it stays disabled while the box is empty, so an accidental save cannot wipe what is stored.
  • A bulk blocklist delete can no longer be used to exhaust memory (#​2354). The request body size limit skipped DELETE entirely, on the assumption that no handler read a body from one. DELETE /blocklist/bulk does, and it is open to any authenticated account, so a large enough body could pin the process while Go grew the buffer to hold it. DELETE bodies are now capped like every other method, and an oversized one is refused with a clear status instead of being decoded.

v1.33.3

Compare Source

Six fixes for things Bindery was getting wrong without ever saying so.

Every entry here is a silence, not an error message. A grab that worked reported as
failed. Books you excluded quietly coming back. An ebook that no quality profile
would ever allow, on a path with no human watching. A track disappearing from a
multi-file audiobook. The one thread running through most of them is a check
answering a question it was never asked, or an absence being read as an answer.

Fixed
  • Grabs against rdt-client and other qBittorrent API emulators are no longer all marked failed (#​2304). Those clients answer POST /torrents/add with HTTP 200 and no body, where qBittorrent itself writes Ok.. Bindery read the empty body as a rejection and failed every grab with add torrent failed: and no message, while the torrent had in fact been accepted, downloaded to completion, and then sat there unimported. An empty body on a 200 is now an accept; a non-empty rejection body such as Fails. still fails the grab, and a response Bindery could not finish reading now fails loudly instead of being mistaken for an empty one. Thanks to Gamegenie13 for the report.
  • A quality profile no longer blocks the format it was never asked about (#​2307). An author gets one quality profile, so if you built yours around audiobook containers (m4b, mp3, flac) then every ebook release for that author was rejected as "format not in quality profile", and the reverse for an ebook profile and audiobook releases. On the Search page that only showed as a misleading warning, since Grab stayed enabled. On the automatic path it was silent and much worse: the book could never be auto-grabbed at all, and the same check runs at import, so a file in the other format would not import either. A release is now judged only against the profile entries of its own media type, and passes when the profile lists none of them. Within a media type the profile does describe, nothing changes: a format you unticked stays rejected, and a profile that deliberately lists both behaves exactly as before. A file whose content belongs to the other media type is still kept out of the wrong slot, which the profile had been doing by accident. Thanks to clebcleb for the report and to KadenTheHero for working out that the profile has no media type to reason with.
  • Series fill no longer re-acquires the books you excluded (#​2302). Every series query returned excluded books, so filling a series marked them wanted and searched for them again, which is the opposite of what excluding a book means, and applying genres to a series wrote them onto excluded books too. Series listings now skip excluded books the way the author listings already did. The one place that still counts them is an import rollback deciding whether a series is now empty, because an excluded book still occupies the series. Thanks to hoxtonia for the report and to thejdubb02 for the fix.
  • An audiobook no longer imports into a "Title (2)" folder when the ebook is already there (#​1959). Under the shared-folder layout, where BINDERY_AUDIOBOOK_DIR is unset so both formats resolve to the same folder, importing a book's audiobook after its ebook created a sibling duplicate instead of joining it. It now merges into the book's existing folder. A same-named file already there, cover art carried by both formats being the usual case, is skipped rather than overwritten, and the skipped names are recorded on the import's History entry and the bookImported notification. Libraries using the per-file audiobook naming template or multi-disc flattening still split, because those paths own the folder they create and merging them safely needs their rollback reworked first. Thanks to Daize for the request and to schmitzkr for the fix.
  • A "Books 1-4" pack is no longer auto-grabbed for a single book (#​2276). An automatic search for one book could select an explicit multi-book release, and since a download is linked to exactly one book, the importer then tried to place every file in the pack into that one book's folder. Automatic selection now skips releases that name themselves as a pack: a numbered range like Books 1-4, a box set, an omnibus, a "complete series". They still appear in interactive search so you can see and grab one deliberately, and if you do, the import is blocked with an explanation instead of running. Queue, Manual import is the way to take a pack. The wording is judged narrowly: Part 1-2 is how a single long audiobook is split and Trilogy is how single books name their series, so neither counts, and if the book you track is itself a bundle then matching packs are still allowed for it. Thanks to magrhino for the report.
  • A multi-file audiobook could lose a track, silently, when two of its files shared a filename (#​2275). Downloads whose book files share no folder below the download root are placed one file at a time and flattened into the book's folder by filename, so two tracks from different source folders with the same name both claimed the same destination. In hardlink mode the second failed with "file exists" and left a half-imported folder the book never recorded; in copy and move mode it silently replaced the first, and in move that track's contents were gone for good. Bindery now projects every destination name before it creates anything and blocks the import, naming both source files and the path they share, with nothing written and both files left in the download folder. The drop-folder handoff had the same flatten and is covered by the same check. A placement error that cannot be predicted, a full disk or a revoked permission, now also undoes what it placed instead of leaving a partial folder that made the next retry build a second one. Hardlink failures also stopped blaming your filesystem layout for unrelated errors: every failed os.Link that was not a cross-device error reported "download dir and library must be on the same filesystem", so a destination collision on a single dataset sent you to check mounts that were fine. A missing source, a permissions problem and an existing destination now each say what they are. Thanks to magrhino for the report.

Configuration

📅 Schedule: (in timezone America/New_York)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate CLI.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
no HelmRelease objects found in cluster

@nerdz-bot
nerdz-bot Bot force-pushed the renovate/ghcr.io-vavallee-bindery-1.x branch 4 times, most recently from 7a12239 to 972dc39 Compare September 5, 2026 18:06
@nerdz-bot nerdz-bot Bot changed the title fix(container): update image ghcr.io/vavallee/bindery ( v1.33.2 ➔ v1.33.3 ) fix(container): update image ghcr.io/vavallee/bindery ( v1.33.2 ➔ v1.33.4 ) Sep 5, 2026
@nerdz-bot
nerdz-bot Bot force-pushed the renovate/ghcr.io-vavallee-bindery-1.x branch from 972dc39 to ac94689 Compare September 6, 2026 01:23
@nerdz-bot nerdz-bot Bot changed the title fix(container): update image ghcr.io/vavallee/bindery ( v1.33.2 ➔ v1.33.4 ) feat(container): update image ghcr.io/vavallee/bindery ( v1.33.2 ➔ v1.34.0 ) Sep 6, 2026
@nerdz-bot
nerdz-bot Bot force-pushed the renovate/ghcr.io-vavallee-bindery-1.x branch 3 times, most recently from 07fc334 to 475eb90 Compare September 7, 2026 10:13
@nerdz-bot
nerdz-bot Bot force-pushed the renovate/ghcr.io-vavallee-bindery-1.x branch from 475eb90 to 7b5c58a Compare September 7, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants