# beets v2.7.0 — Release v2.7.0 - Product: beets (https://whatsnew.fyi/product/beets) - Vendor: Adrian Sampson - Date: 2026-03-07 - Version: v2.7.0 - Original notes: https://github.com/beetbox/beets/releases/tag/v2.7.0 - Permalink: https://whatsnew.fyi/product/beets/releases/v2.7.0 - Labels: Platforms: Desktop What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog. Reuse: the summaries, labels and curation here are © What's New. Quote freely with attribution and a link back; wholesale republication of the corpus is not permitted — terms: https://whatsnew.fyi/terms. The vendors' own release notes remain their publishers'. --- - **added** — Add native support for multiple genres per album/track with the genres field storing genres as a list and written to files as multiple individual genre tags - **added** — LastGenre Plugin: Add cleanup_existing configuration flag to allow whitelist canonicalization of existing genres - **changed** — MusicBrainz Plugin, Beatport Plugin, Discogs Plugin and LastGenre Plugin have been updated to populate the genres field as a list - **changed** — Lyrics Plugin: With synced enabled, existing synced lyrics are no longer replaced by newly fetched plain lyrics even when force is enabled - **changed** — Lyrics Plugin: Remove Source: suffix from lyrics and store the backend name in lyrics_backend, URL in lyrics_url, language in lyrics_language and translation language in lyrics_translation_language flexible attributes - **changed** — Edit Plugin: Editing multi-valued fields now behaves more naturally with list values handled directly - **changed** — LastGenre Plugin: Remove the separator configuration option - **changed** — Lyrics Plugin: Synced lyrics from lrclib source are now checked to ensure the final verse falls within the track's duration - **changed** — modify command: Use semicolon followed by space as the separator to delimit multiple field values instead of \␀ - **fixed** — Convert Plugin: Fix extension substitution inside path of the exported playlist - **fixed** — FetchArt Plugin: Prevent deletion of configured fallback cover art - **fixed** — FtInTitle Plugin: Fix handling of multiple featured artists with ampersand - **fixed** — Fuzzy Search Plugin: Force slow query evaluation whenever the fuzzy prefix is used so fuzzy matching is applied consistently - **fixed** — Fuzzy Search Plugin: Improve fuzzy matching when the query is shorter than the field value so substring-style searches produce more useful results - **fixed** — import command: Duplicate detection now works for as-is imports when autotag is disabled - **fixed** — import command: When autotagging, initialise empty multi-valued fields with None instead of empty list to avoid overwriting existing metadata - **fixed** — Zero Plugin: When the omit_single_disc option is set, disctotal is zeroed alongside disc - **deprecated** — Populating the single genre field in metadata source plugins is deprecated and support will be removed in version 3.0.0; populate the genres list instead #### New features - [LastGenre Plugin](https://beets.readthedocs.io/en/stable/plugins/lastgenre.html): Added `cleanup_existing` configuration flag to allow whitelist canonicalization of existing genres. - Add native support for multiple genres per album/track. The `genres` field now stores genres as a list and is written to files as multiple individual genre tags (e.g., separate GENRE tags for FLAC/MP3). The [MusicBrainz Plugin](https://beets.readthedocs.io/en/stable/plugins/musicbrainz.html), [Beatport Plugin](https://beets.readthedocs.io/en/stable/plugins/beatport.html), [Discogs Plugin](https://beets.readthedocs.io/en/stable/plugins/discogs.html) and [LastGenre Plugin](https://beets.readthedocs.io/en/stable/plugins/lastgenre.html) plugins have been updated to populate the `genres` field as a list. **Migration**: Existing libraries with comma-separated, semicolon-separated, or slash-separated genre strings (e.g., `"Rock, Alternative, Indie"`) are automatically migrated to the `genres` list when you first run beets after upgrading. The migration runs once when the database schema is updated, splitting genre strings and writing the changes to the database. The updated `genres` values will be written to media files the next time you run a command that writes tags (such as [write command](https://beets.readthedocs.io/en/stable/reference/cli.html#write-cmd) or during import). No manual action or [MBSync Plugin](https://beets.readthedocs.io/en/stable/plugins/mbsync.html) is required. The `genre` field is split by the first separator found in the string, in the following order of precedence: 1. [LastGenre Plugin](https://beets.readthedocs.io/en/stable/plugins/lastgenre.html) `separator` configuration 2. Semicolon followed by a space 3. Comma followed by a space 4. Slash wrapped by spaces - [Lyrics Plugin](https://beets.readthedocs.io/en/stable/plugins/lyrics.html): With `synced` enabled, existing synced lyrics are no longer replaced by newly fetched plain lyrics, even when `force` is enabled. - [Lyrics Plugin](https://beets.readthedocs.io/en/stable/plugins/lyrics.html): Remove `Source: ` suffix from lyrics. Store the backend name in `lyrics_backend`, URL in `lyrics_url`, language in `lyrics_language` and translation language (if translations present) in `lyrics_translation_language` flexible attributes. Lyrics are automatically migrated on the first beets run. :bug: (#6370) #### Bug fixes - [Convert Plugin](https://beets.readthedocs.io/en/stable/plugins/convert.html): Fix extension substitution inside path of the exported playlist. - [FetchArt Plugin](https://beets.readthedocs.io/en/stable/plugins/fetchart.html): Prevent deletion of configured fallback cover art - [FtInTitle Plugin](https://beets.readthedocs.io/en/stable/plugins/ftintitle.html): Fix handling of multiple featured artists with ampersand. - [Fuzzy Search Plugin](https://beets.readthedocs.io/en/stable/plugins/fuzzy.html): Force slow query evaluation whenever the fuzzy prefix is used (for example `~foo` or `%%foo`), so fuzzy matching is applied consistently. :bug: (#5638) - [Fuzzy Search Plugin](https://beets.readthedocs.io/en/stable/plugins/fuzzy.html): Improve fuzzy matching when the query is shorter than the field value so substring-style searches produce more useful results. :bug: (#2043) - [import command](https://beets.readthedocs.io/en/stable/reference/cli.html#import-cmd) Duplicate detection now works for as-is imports (when `autotag` is disabled). Previously, `duplicate_keys` and `duplicate_action` config options were silently ignored for as-is imports. - [import command](https://beets.readthedocs.io/en/stable/reference/cli.html#import-cmd) When autotagging, initialise empty multi-valued fields with `None` instead of empty list, which caused beets to overwrite existing metadata with empty list values instead of leaving them unchanged. :bug: (#6403) - [Zero Plugin](https://beets.readthedocs.io/en/s _[Truncated at 4000 characters — full notes: https://github.com/beetbox/beets/releases/tag/v2.7.0]_