-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Normal
-
Affects Version/s: 3.0.0b9
-
Component/s: Webservice & Networking
-
None
After logging in to MusicBrainz via the browser integration flow, Picard immediately re-prompts for authentication and fails to load collections:
{{ E: Network request error for https://musicbrainz.org/ws/2/collection ->
AuthenticationRequiredError (HTTP 401)
I: MusicBrainz authentication declined
E: Error loading collections: Authorization required}}
i.e. login appears to succeed (the /auth callback returns 200 and stores a token), but the token does not carry the expected permissions.
Root cause:
Picard requests OAuth scopes in two places, and they disagree:
- picard/tagger.py (mb_login) builds the authorization URL with the correct, prefixed scopes:
profile musicbrainz:tag musicbrainz:rating musicbrainz:collection
musicbrainz:submit_isrc musicbrainz:submit_barcode
- picard/browser/server.py (the /auth callback that exchanges the authorization code) still used the OLD, unprefixed scopes:
profile tag rating collection submit_isrc submit_barcode
OAuthManager.on_exchange_authorization_code_finished() persists the scopes string passed to exchange_authorization_code() together with the refresh token (set_refresh_token(refresh_token, scopes)). Because the browser callback passed unprefixed scopes, the stored token is associated with the wrong scope set, so subsequent authorized requests (e.g. GET /ws/2/collection) return HTTP 401 and Picard shows the login dialog again right after logging in.
The MusicBrainz/MetaBrainz server migrated scope names to the "musicbrainz:" prefix; PICARD-2772 ("Use new MetaBrainz oauth endpoint", 2026-07-27) updated the scopes in tagger.py but did not update picard/browser/server.py, so the two code paths drifted.
Steps to reproduce:
1. Enable browser integration.
2. Log in to MusicBrainz from Picard (Options or the login action).
3. Complete authorization in the browser.
4. Observe: the login dialog reappears and/or "Error loading collections:
Authorization required" is shown; collections do not load.
Expected: after a successful login, the token carries all requested scopes and collections load without re-prompting.