diff --git a/beetsplug/beatport.py b/beetsplug/beatport.py index c07cce72f..d8a6460e8 100644 --- a/beetsplug/beatport.py +++ b/beetsplug/beatport.py @@ -457,6 +457,16 @@ class BeatportPlugin(MetadataSourcePlugin): # Strip medium information from query, Things like "CD1" and "disk 1" # can also negate an otherwise positive result. query = re.sub(r"\b(CD|disc)\s*\d+", "", query, flags=re.I) + + # query may be empty strings + # We want to skip the lookup in this case. + if not query.strip(): + self._log.debug( + "Empty search query after preprocessing, skipping {.data_source}.", + self, + ) + return + for beatport_release in self.client.search(query, "release"): if beatport_release is None: continue @@ -522,8 +532,18 @@ class BeatportPlugin(MetadataSourcePlugin): """ return self.get_artist(artists=artists, id_key=0, name_key=1) - def _get_tracks(self, query): + def _get_tracks(self, query: str): """Returns a list of TrackInfo objects for a Beatport query.""" + + # query may be empty strings + # We want to skip the lookup in this case. + if not query.strip(): + self._log.debug( + "Empty search query after preprocessing, skipping {.data_source}.", + self, + ) + return [] + bp_tracks = self.client.search(query, release_type="track") tracks = [self._get_track_info(x) for x in bp_tracks] return tracks diff --git a/beetsplug/discogs.py b/beetsplug/discogs.py index be1cf97fa..8d4d4d432 100644 --- a/beetsplug/discogs.py +++ b/beetsplug/discogs.py @@ -231,7 +231,10 @@ class DiscogsPlugin(MetadataSourcePlugin): return track_info def item_candidates( - self, item: Item, artist: str, title: str + self, + item: Item, + artist: str, + title: str, ) -> Iterable[TrackInfo]: albums = self.candidates([item], artist, title, False) @@ -291,6 +294,15 @@ class DiscogsPlugin(MetadataSourcePlugin): # can also negate an otherwise positive result. query = re.sub(r"(?i)\b(CD|disc|vinyl)\s*\d+", "", query) + # query may be empty strings + # We want to skip the lookup in this case. + if not query.strip(): + self._log.debug( + "Empty search query after preprocessing, skipping {.data_source}.", + self, + ) + return [] + try: results = self.discogs_client.search(query, type="release") results.per_page = self.config["search_limit"].get() diff --git a/beetsplug/musicbrainz.py b/beetsplug/musicbrainz.py index 8e259e94b..2335ae757 100644 --- a/beetsplug/musicbrainz.py +++ b/beetsplug/musicbrainz.py @@ -807,6 +807,11 @@ class MusicBrainzPlugin(MetadataSourcePlugin): self._log.debug( "Searching for MusicBrainz {}s with: {!r}", query_type, filters ) + + if not filters: + self._log.debug("No valid filters provided, skipping search.") + return [] + try: method = getattr(musicbrainzngs, f"search_{query_type}s") res = method(limit=self.config["search_limit"].get(), **filters) diff --git a/beetsplug/spotify.py b/beetsplug/spotify.py index 7cb9e330d..2dfa7bedf 100644 --- a/beetsplug/spotify.py +++ b/beetsplug/spotify.py @@ -434,6 +434,13 @@ class SpotifyPlugin( filters=filters, query_string=query_string ) + if not query.strip(): + self._log.debug( + "Empty search query after applying filters, skipping {.data_source}.", + self, + ) + return [] + self._log.debug("Searching {.data_source} for '{}'", self, query) try: response = self._handle_response( diff --git a/docs/changelog.rst b/docs/changelog.rst index 81e8853d3..9d1ab092c 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -15,13 +15,18 @@ New features: Bug fixes: +- :doc:`plugins/discogs`, :doc:`plugins/beatport`, :doc:`plugins/spotify`, + :doc:`plugins/musicbrainz`: Fix an issue where no metadata in a file would + crash the import process :bug:`6060` + For packagers: Other changes: -- Standardized ``search_*`` parameter handling in autotag matchers. Manual album and - singleton searches now behave consistently: when the prompt does not specify a - search query, the system defaults to using the corresponding metadata value. +- Standardized ``search_*`` parameter handling in autotag matchers. Manual album + and singleton searches now behave consistently: when the prompt does not + specify a search query, the system defaults to using the corresponding + metadata value. 2.5.1 (October 14, 2025) ------------------------