[GH-ISSUE #1221] Local Tracks Not Recognized as URI #712

Open
opened 2026-02-28 00:01:06 +03:00 by kerem · 2 comments
Owner

Originally created by @ed-macke on GitHub (Dec 4, 2025).
Original GitHub issue: https://github.com/spotipy-dev/spotipy/issues/1221

Describe the bug
The client.py _is_uri() method is throwing an exception when the track is a local file.

When the URI is something "normal", like "spotify:track:7hK9jnESeCfc5fIHH76jKh", the _is_uri() method recognizes it as valid via the regex match.

However, when the URI is for a local track, like "spotify:local:Toot+Sweet:Celtic+Christmas:Christmas+Medley:248", the _is_uri() regex match fails. It then calls _get_id("track", "spotify:local:Toot+Sweet:Celtic+Christmas:Christmas+Medley:248"), and none of the matches work in that function and it eventually throws an Unsupported URL SpotifyException (currently on line 2139).

Your code
I have a list of URIs that I've retrieved via client.playlist_items().

When I call the following function, passing that list of URIs, that's when the exception is thrown.

self.api.playlist_replace_items(playlist_id, uris[:100])

spotipy.exceptions.SpotifyException: http status: 400, code: -1 - Unsupported URL / URI., reason: None

Expected behavior
The function works without throwing an exception

Output
(self.api is an instance of the Spotify class)
(playlist is an object with an id attribute)

File "D:\Documents\Python\spotify-backup\spotify_api.py", line 94, in update_tracks
self.api.playlist_replace_items(playlist.id, uris[:chunk]) # Replace playlist's first 100 items (limit of Spotify)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Python\Lib\site-packages\spotipy\client.py", line 1187, in playlist_replace_items
ftracks = [self._get_uri("track", tid) for tid in items]
~~~~~~~~~~~~~^^^^^^^^^^^^^^
File "C:\Python\Lib\site-packages\spotipy\client.py", line 2145, in _get_uri
return "spotify:" + type + ":" + self._get_id(type, id)
~~~~~~~~~~~~^^^^^^^^^^
File "C:\Python\Lib\site-packages\spotipy\client.py", line 2139, in _get_id
raise SpotifyException(400, -1, "Unsupported URL / URI.")
spotipy.exceptions.SpotifyException: http status: 400, code: -1 - Unsupported URL / URI., reason: None

Environment:

  • OS: Windows 11
  • Python version: 3.14.0
  • spotipy version: 2.25.2
  • your IDE: PyCharm

Additional context
I believe the fix would be to modify the _regex_spotify_uri regex pattern to account for the local file syntax, although I'm not sure what the Spotify syntax spec for local files is.

It looks like it might be spotify:local:artist_name:album_name:track_name:number.
My local file is:
Artist: Toot Sweet
Album: Celtic Christmas
Title: Christmas Medley
Filename: "Christmas Medley.mp3"

and the Spotify URI for it is "spotify:local:Toot+Sweet:Celtic+Christmas:Christmas+Medley:248". I have no idea what the '248' indicates.

FYI, the type parameter being passed is "track".

Originally created by @ed-macke on GitHub (Dec 4, 2025). Original GitHub issue: https://github.com/spotipy-dev/spotipy/issues/1221 **Describe the bug** The client.py _is_uri() method is throwing an exception when the track is a local file. When the URI is something "normal", like "spotify:track:7hK9jnESeCfc5fIHH76jKh", the _is_uri() method recognizes it as valid via the regex match. However, when the URI is for a local track, like "spotify:local:Toot+Sweet:Celtic+Christmas:Christmas+Medley:248", the _is_uri() regex match fails. It then calls _get_id("track", "spotify:local:Toot+Sweet:Celtic+Christmas:Christmas+Medley:248"), and none of the matches work in that function and it eventually throws an Unsupported URL SpotifyException (currently on line 2139). **Your code** I have a list of URIs that I've retrieved via client.playlist_items(). When I call the following function, passing that list of URIs, that's when the exception is thrown. self.api.playlist_replace_items(playlist_id, uris[:100]) spotipy.exceptions.SpotifyException: http status: 400, code: -1 - Unsupported URL / URI., reason: None **Expected behavior** The function works without throwing an exception **Output** (self.api is an instance of the Spotify class) (playlist is an object with an **id** attribute) File "D:\Documents\Python\spotify-backup\spotify_api.py", line 94, in update_tracks self.api.playlist_replace_items(playlist.id, uris[:chunk]) # Replace playlist's first 100 items (limit of Spotify) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Python\Lib\site-packages\spotipy\client.py", line 1187, in playlist_replace_items ftracks = [self._get_uri("track", tid) for tid in items] ~~~~~~~~~~~~~^^^^^^^^^^^^^^ File "C:\Python\Lib\site-packages\spotipy\client.py", line 2145, in _get_uri return "spotify:" + type + ":" + self._get_id(type, id) ~~~~~~~~~~~~^^^^^^^^^^ File "C:\Python\Lib\site-packages\spotipy\client.py", line 2139, in _get_id raise SpotifyException(400, -1, "Unsupported URL / URI.") spotipy.exceptions.SpotifyException: http status: 400, code: -1 - Unsupported URL / URI., reason: None **Environment:** - OS: Windows 11 - Python version: 3.14.0 - spotipy version: 2.25.2 - your IDE: PyCharm **Additional context** I believe the fix would be to modify the _regex_spotify_uri regex pattern to account for the local file syntax, although I'm not sure what the Spotify syntax spec for local files is. It looks like it might be spotify:local:artist_name:album_name:track_name:number. My local file is: **Artist:** Toot Sweet **Album:** Celtic Christmas **Title:** Christmas Medley **Filename:** "Christmas Medley.mp3" and the Spotify URI for it is "spotify:local:Toot+Sweet:Celtic+Christmas:Christmas+Medley:248". I have no idea what the '248' indicates. FYI, the **type** parameter being passed is "track".
Author
Owner

@ed-macke commented on GitHub (Dec 4, 2025):

I tweaked the regex value so that local files were recognized as valid, but when the API call was actually made, I got a different error: Invalid base62 id, reason: None.

Gemini says that's because "The playlists/{plid}/tracks endpoint in the Spotify Web API is not designed to support local files. The Spotify Web API does not currently allow adding local files to playlists, though it can reorder or remove existing local file tracks that were added using the desktop app."

Well, that's not fantastic.

If that's the case, I have a suggestion for improvement... if the app sees one of those local file URIs, throw an exception like raise SpotifyException('Spotify does not allow adding local files')

<!-- gh-comment-id:3613247595 --> @ed-macke commented on GitHub (Dec 4, 2025): I tweaked the regex value so that local files were recognized as valid, but when the API call was actually made, I got a different error: **Invalid base62 id, reason: None**. Gemini says that's because _"The playlists/{plid}/tracks endpoint in the Spotify Web API is not designed to support local files. The Spotify Web API does not currently allow adding local files to playlists, though it can reorder or remove existing local file tracks that were added using the desktop app."_ Well, that's not fantastic. If that's the case, I have a suggestion for improvement... if the app sees one of those local file URIs, throw an exception like raise SpotifyException('Spotify does not allow adding local files')
Author
Owner

@dieser-niko commented on GitHub (Dec 23, 2025):

Sorry for the late reply.

Please check out the linked PR, I've implemented your suggestion.

<!-- gh-comment-id:3687610284 --> @dieser-niko commented on GitHub (Dec 23, 2025): Sorry for the late reply. Please check out the linked PR, I've implemented your suggestion.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/spotipy#712
No description provided.