New features
- Convert Plugin: Add new configuration option
convert.refreshand command-line option--refresh, allowing to force Convert Plugin operation when original file is newer than existing converted file. - Edit Plugin: The interactive import editor now shows album-level fields (as configured by
albumfields) as a YAML header section when editing an album import. Fields that appear in bothitemfieldsandalbumfieldsare shown only in the header, not per-track. - FetchArt Plugin: Add
fetch_for_asissetting that enables fetching album art from online sources even when imported files are not modified by the auto-tagger. Default isnowhich means FetchArt Plugin looks for art only in the local filesystem when the user (orquiet_fallback) choosesasis. - FtInTitle Plugin: Apply featured-artist rewriting to fetched metadata before commands such as MBSync Plugin use it. 🐛 (#1153)
- LastGenre Plugin: Add support for normalizing genre spellings and naming variants with a new configuration option
aliases. The feature is enabled by default and ships with a built-in list of regex patterns. These patterns can be replaced via the user's configuration. The default whitelist and genre tree were audited against the top 1,000 Last.fm tags: canonical names are now consistent across both files, long-standing mismatches between them have been resolved, and entries align with the built-in alias patterns. 🐛 (#6466) - Lyrics Plugin: Add
lrcmuxbackend, which aggregates lyrics from various other sources. - Lyrics Plugin: Added a
--no-keep-syncedcommand option to overridekeep_synced: yesfor a single manual lyrics fetch. - Lyrics Plugin: Added a
rest_directoryconfiguration option for specifying a reStructuredText output directory, semantically equivalent to-r, --write-rest. 🐛 (#2806) - modify command: Support
+=and-=operators to add or remove individual values from multi-valued fields without replacing the whole field. 🐛 (#6587) - ReplayGain Plugin: Add a
metaflacbackend that computes ReplayGain for FLAC files using themetaflaccommand-line tool. 🐛 (#1203) - Spotify Plugin: Recognize native Spotify URIs (e.g.
spotify:album:<id>andspotify:track:<id>) when extracting release/track IDs, in addition to fullopen.spotify.comURLs and bare IDs - Tidal Plugin: Add cover art support. Album metadata now includes
cover_art_urlfrom Tidal'scoverArtrelationship, which the FetchArt Plugin plugin can retrieve. - A database backup is now automatically created before running schema migrations. Control with the
create_backup_before_migrationsoption (default: yes).
Bug fixes
- Convert Plugin:
convert -awithcopy_album_artenabled no longer crashes when the stored album art path points to a missing file (for example a multi-disc album whose cover lives in the album root rather than a per-disc directory); the missing art is skipped instead. 🐛 (#4692) - Edit Plugin: Preserve missing album art paths when editing album metadata, instead of turning
artpath: nullinto a path ending inNone. 🐛 (#2438) - ImportFeeds Plugin: import command no longer aborts the whole run when a symlink cannot be created (e.g. on Windows or a read-only directory); the failure is logged and the import continues. 🐛 (#840)
- Lyrics Plugin: Leave lyrics empty when a source reports an instrumental track, and store that state in
lyrics_instrumentalflexible attribute. Existing[Instrumental]lyrics are migrated automatically. 🐛 (#6719) - Missing Plugin: Honor the
-f/--formatoption (and theformat_albumconfiguration) when listing missing albums in album mode. 🐛 (#3804) - Smart Playlist Plugin:
splupdateno longer crashes withTypeError: unhashable type: 'list'when a playlist configuration includes aplaylist:query. 🐛 (#5354) - SubsonicUpdate Plugin: Log a clearer error when the Subsonic server returns a non-JSON response. 🐛 (#5635)
- Tidal Plugin: Normalize Tidal album types to lowercase.
- A date query containing a stray
|(for exampleadded:2000|2001, as might be typed by a user expecting|to mean "or") now raises a clean "a valid date/time string" error instead of crashing with an uncaughtKeyError. A|was being accepted as a relative-date unit due to a regular expression character-class typo. - Album
storeno longer copiesartpathonto its items as an absolute path, which broke relative-path portability. A database migration removes any such staleartpathattributes left on items by earlier versions. 🐛 (#6756) - Sorting by a nullable field (for example a flexible attribute with a declared type whose null value is
None) that is present on only some items no longer crashes with aTypeError. Missing values are now grouped together, ordered before present ones when sorting ascending and after them when descending. 🐛 (#3461)
Other changes
- Contributing: The project now uses
uvfor packaging, virtual environment, and dependency management, replacingpoetry. The build backend has changed frompoetry-coretohatchling. Please see updates in Development Tools and Getting the Source for more information. 🐛 (#5783) - Installation Add Homebrew to the list of supported package managers in the installation guide.
- Installation: Note that Windows users should run beets in a terminal emulator (such as Windows Terminal or cmder) for output to display correctly. 🐛 (#2848)
- Installation: Switch isolated tool installation guidance and GitHub workflow setup to
uv toolcommands. - LastGenre Plugin: Add a new "Choosing the Right Tool" documentation section to guide users in picking the right approach across genre fetching, filtering, and normalization.
- Spotify Plugin: Retry on
503 Service Unavailableresponses from the Spotify API instead of immediately aborting, matching the existing429rate-limit retry behavior.