Skip to content

Releases: linuxserver/docker-beets

2.11.0-ls332

22 May 20:32
af6c2fc

Choose a tag to compare

CI Report:

https://ci-tests.linuxserver.io/linuxserver/beets/2.11.0-ls332/index.html

LinuxServer Changes:

Full Changelog: 2.11.0-ls331...2.11.0-ls332

Remote Changes:

Updating PIP version of beets to 2.11.0

nightly-da16db11-ls290

22 May 13:36
6ba54fc

Choose a tag to compare

Pre-release

CI Report:

https://ci-tests.linuxserver.io/linuxserver/beets/nightly-da16db11-ls290/index.html

LinuxServer Changes:

Full Changelog: nightly-6dd62516-ls289...nightly-da16db11-ls290

Remote Changes:

docs: adding beets-getlrc to the 'other plugins' list (#6664)

Description

I added a plugin i made to the docs (index.rst). I made sure to add a
link to my github repo for the project. Nothing else was changed.

nightly-6dd62516-ls289

21 May 16:48
7b5661a

Choose a tag to compare

Pre-release

CI Report:

https://ci-tests.linuxserver.io/linuxserver/beets/nightly-6dd62516-ls289/index.html

LinuxServer Changes:

Full Changelog: nightly-4746d852-ls288...nightly-6dd62516-ls289

Remote Changes:

Fix album modify splitting multi-value field strings into individual characters (#6653)

Fixes #5690

Problem

When running beet mod -a artists=Charli XCX in album mode, the
artists tag value gets split into individual characters on disk. Item
mode (beet mod without -a) works correctly.

Root Cause

  1. Album._type(artists) returns DEFAULT (artists is not an Album
    fixed field), so Album._parse returns a plain string.
  2. When Album.store() propagates to items,
    MULTI_VALUE_DSV.normalize(value) falls through to model_type(value)
    = list(value), splitting the string into characters.

Fix

  1. DelimitedString.normalize (types.py): Handle string input by
    parsing it (splitting by delimiter if present) instead of list(). This
    prevents character-level splitting.
  2. Model._type (db.py): Fall back to the related models field
    definitions so multi-value types (e.g. MULTI_VALUE_DSV for artists)
    are recognized on both Album and Item models.

nightly-c9df7a94-ls288

20 May 02:19
578b840

Choose a tag to compare

Pre-release

CI Report:

https://ci-tests.linuxserver.io/linuxserver/beets/nightly-c9df7a94-ls288/index.html

LinuxServer Changes:

No changes

Remote Changes:

fix(hooks): chain original error when cached_property AttrDict lookup fails (#6558) (#6564)

Fixes #6558.

Problem

When a cached_property on an AttrDict subclass raises
AttributeError during its own computation, Python's attribute lookup
falls back to __getattr__ with the property's own name. That masks the
real missing field behind a misleading traceback like:

AttributeError: 'AlbumInfo' object has no attribute 'raw_data'

…even though raw_data exists on the instance and the code inside
raw_data is what blew up on a missing sibling attribute. Users and
maintainers hit this both on #6558 and on the earlier #6503 / #6506
reports (different metadata providers, same masking shape).

Fix

In AttrDict.__getattr__, if the looked-up class attribute is a
cached_property, invoke it explicitly. If it raises AttributeError,
re-raise as RuntimeError with from exc so the original cause is
preserved on the traceback and names the attribute that actually failed.

Plain missing-attribute behaviour (obj.nope on an AttrDict) is
unchanged — that still raises AttributeError as before.

Tests

Added a regression class TestAttrDictCachedPropertyMasking in
test/autotag/test_hooks.py covering:

  1. real missing attr in a cached_property body surfaces as
    RuntimeError naming the missing field
  2. the RuntimeError.__cause__ is the original AttributeError
  3. a plain missing attr on an AttrDict still raises AttributeError
  4. existing dict-key access (obj.title) still works

Full test/autotag/test_hooks.py suite: 90 passed locally.

Follow-up

Picked approach (1) from @snejus' comment on #6558
(beetbox/beets#6558 (comment)).
Happy to iterate on the exception type or wording.

nightly-4746d852-ls288

19 May 22:18
578b840

Choose a tag to compare

Pre-release

CI Report:

https://ci-tests.linuxserver.io/linuxserver/beets/nightly-4746d852-ls288/index.html

LinuxServer Changes:

Full Changelog: nightly-aa33b1cb-ls287...nightly-4746d852-ls288

Remote Changes:

core/structure: create a separate module for sorting in dbcore (#6644)

This PR moves all sorting-related classes from beets.dbcore.query into
a new dedicated module, beets.dbcore.sort. All references and imports
throughout the codebase and tests are updated to use the new module. No
functional changes are introduced - this is a mechanical refactor to
improve code organization and separation of concerns.

High-level impact:

  • Sorting logic is now isolated in beets.dbcore.sort, making the
    architecture clearer.
  • All code using sort classes (e.g., Sort, FixedFieldSort,
    MultipleSort, etc.) now imports them from beets.dbcore.sort instead
    of beets.dbcore.query.
  • No changes to public APIs or behavior; only import paths and module
    boundaries are affected.

This change lays groundwork for future maintainability and makes the
codebase easier to navigate for contributors.

nightly-fc9c02a4-ls287

17 May 15:57
47e39df

Choose a tag to compare

Pre-release

CI Report:

https://ci-tests.linuxserver.io/linuxserver/beets/nightly-fc9c02a4-ls287/index.html

LinuxServer Changes:

No changes

Remote Changes:

Fix command desc formatting in help (#6646)

No impact on core logic, only on CLI help output formatting.

This PR fixes the formatting of command descriptions in the CLI help
output.

  • Command descriptions had historically been printed inline, however
    9352a79 introduced a bug which moved them to the next line, making the
    help output very verbose.
  • Now, descriptions again appear inline with the command name (e.g.,
    config show or edit the user configuration), improving readability and
    consistency.
  • A regression test (test_help) is included to verify the new output
    format and prevent future breakage.

High-level impact: CLI help output is more user-friendly, with no effect
on core logic or APIs.

Before

image

After

image

nightly-aa33b1cb-ls287

17 May 05:49
47e39df

Choose a tag to compare

Pre-release

CI Report:

https://ci-tests.linuxserver.io/linuxserver/beets/nightly-aa33b1cb-ls287/index.html

LinuxServer Changes:

Full Changelog: nightly-44f7bf80-ls286...nightly-aa33b1cb-ls287

Remote Changes:

fix: duplicate album merge broken in threaded import mode (#6623)

Fixes #6601

Added import contextvars and changed _extend_pipeline to capture the
current context and run the inner pipeline within it to ensure the
music_dir context variable is available when the inner pipeline
resolves paths, preventing the relative-path bug that caused could not
get filesize errors and removing 0 old duplicated items during merge.

Works perfectly after the fix:

arsaboo@arsmusic:~$ beet import -m -I -t ~/shared/music/ --set genre="Filmi" --search-id 7MwKD3kEFMov4LQqyhnmzL

/home/arsaboo/shared/music (1 items)

  Match (75.2%):
  King - Lukkhe
  ≠ artist, tracks
  Spotify, None, 2026, None, Warner Music India, None, None
  https://open.spotify.com/album/7MwKD3kEFMov4LQqyhnmzL
  ≠ Artist: King; OAFF; Savera; Sunny M.R. -> King
  * Album: Lukkhe
     ≠ (#2) Khamoshiyaan (3:03) -> (#2) Khamoshiyaan (feat. Romy & Manreet Khara) (3:03)
Missing tracks (13/14 - 92.9%):
 ! Bulletproof (#1) (3:09)
 ! Jee Lenge (#3) (3:25)
 ! Headshot (#4) (3:10)
 ! Ruh Teri (feat. Manreet Khara & Agrim Joshi) (#5) (2:31)
 ! Roobaroo (#6) (3:17)
 ! Savere (#7) (2:29)
 ! Haal (#8) (3:29)
 ! Haal (The Journey) (#9) (6:13)
 ! Nachdi Shaam (#10) (2:22)
 ! Hoga Bada Mera Naam (#11) (1:58)
 ! All Eyes On Us (#12) (3:13)
 ! Swan Song (Hoya Azaad) (#13) (3:17)
 ! Bhaari Pangey (#14) (2:19)
➜ [A]pply, More candidates, Skip, Use as-is, as Tracks, Group albums,
Enter search, enter Id, aBort, eDit, edit Candidates, Print tracks,
Open files with Picard? a
This album is already in the library!
Old: 3 items, MP3, 320kbps, 9:45, 22.9 MiB
New: 1 items, MP3, 320kbps, 3:03, 7.8 MiB
➜ [S]kip new, Keep all, Remove old, Merge all? m

/home/arsaboo/shared/music
/data/music/Hindi Music/L/Lukkhe [30718] (2026)/Lukkhe (2026) - Bulletproof.mp3
/data/music/Hindi Music/L/Lukkhe [30718] (2026)/Lukkhe (2026) - Headshot.mp3
/data/music/Hindi Music/L/Lukkhe [30718] (2026)/Lukkhe (2026) - Jee Lenge.mp3 (4 items)

  Match (82.6%):
  King - Lukkhe
  ≠ artist, tracks
  Spotify, None, 2026, None, Warner Music India, None, None
  https://open.spotify.com/album/7MwKD3kEFMov4LQqyhnmzL
  ≠ Artist: OAFF; Savera; Ruaa Kayy; Romy; Manreet Khara -> King
  * Album: Lukkhe
     * (#1) Bulletproof (3:09)
     ≠ (#2) Khamoshiyaan (3:03) -> (#2) Khamoshiyaan (feat. Romy & Manreet Khara) (3:03)
     * (#3) Jee Lenge (3:25)
     * (#4) Headshot (3:10)
Missing tracks (10/14 - 71.4%):
 ! Ruh Teri (feat. Manreet Khara & Agrim Joshi) (#5) (2:31)
 ! Roobaroo (#6) (3:17)
 ! Savere (#7) (2:29)
 ! Haal (#8) (3:29)
 ! Haal (The Journey) (#9) (6:13)
 ! Nachdi Shaam (#10) (2:22)
 ! Hoga Bada Mera Naam (#11) (1:58)
 ! All Eyes On Us (#12) (3:13)
 ! Swan Song (Hoya Azaad) (#13) (3:17)
 ! Bhaari Pangey (#14) (2:19)
➜ [A]pply, More candidates, Skip, Use as-is, as Tracks, Group albums,
Enter search, enter Id, aBort, eDit, edit Candidates, Print tracks,
Open files with Picard? a

nightly-d741a464-ls286

16 May 11:04
05eacc4

Choose a tag to compare

Pre-release

CI Report:

https://ci-tests.linuxserver.io/linuxserver/beets/nightly-d741a464-ls286/index.html

LinuxServer Changes:

Full Changelog: nightly-5df37abc-ls285...nightly-d741a464-ls286

Remote Changes:

core/structure: move UserError to beets.exceptions (#6643)

Update all references in core, plugins, and tests to import UserError
from the new location. This centralizes exception handling and improves
code organization.

nightly-44f7bf80-ls286

16 May 11:53
05eacc4

Choose a tag to compare

Pre-release

CI Report:

https://ci-tests.linuxserver.io/linuxserver/beets/nightly-44f7bf80-ls286/index.html

LinuxServer Changes:

No changes

Remote Changes:

Fix path format queries for multi-valued fields (#6635)

Fixes #6598.

the issue was that path format queries are evaluated against an
in-memory Item using query.match(), where multi-valued fields such as
genres are represented as lists, e.g. ["Classical"]. Before this change,
string/exact matching treated that list as one whole value, so a path
rule like genres:=~Classical: _Classical/... failed to match and fell
back to the default path format, even though beet list
genres:=~Classical worked through the database query path. This change
updates in-memory matching so sequence-like field values are matched
element by element, while excluding strings and byte-like values from
sequence handling. I added regression tests for genres:=~Classical,
genres:=Classical, avoiding a false positive for Neoclassical, and
direct query.match() behavior on multi-valued fields. Manual
verification showed the original version returned match: False and
destination: ...\one\two, while the fixed version returns match: True
and destination: ...\one\three.

Summary

This fixes path format selection for multi-valued fields such as
genres.

Path format queries are evaluated against an in-memory Item via
query.match().
For multi-valued fields, the in-memory value is a list, for example:

genres = ["Classical"]

2.11.0-ls331

15 May 20:18
37817ab

Choose a tag to compare

CI Report:

https://ci-tests.linuxserver.io/linuxserver/beets/2.11.0-ls331/index.html

LinuxServer Changes:

Full Changelog: 2.11.0-ls330...2.11.0-ls331

Remote Changes:

Updating PIP version of beets to 2.11.0