[GH-ISSUE #1508] Starting playback of several tracks via their URIs #684

Closed
opened 2026-02-27 19:31:56 +03:00 by kerem · 5 comments
Owner

Originally created by @maliavko on GitHub (Jun 10, 2025).
Original GitHub issue: https://github.com/librespot-org/librespot/issues/1508

Description

Starting playback from Spotify Web API for several tracks via list of URIs generates an error response, when the current playback device is Librespot.

{
   "error" : {
     "status" : 403,
     "message" : "Player command failed: Restriction violated",
     "reason" : "UNKNOWN"
   }
}

If the device is official Spotify desktop client or web-page - everything goes well.

Request body example:

{
"uris":["spotify:track:1ZyQEn0iceHj0Lbt6I6Op3"]
}

Version

Built from sources on Windows
librespot 0.6.0-dev 8b72954 (Built on 2025-06-02, Build ID: BQcgs54b, Profile: release)

How to reproduce

Steps to reproduce the behavior in librespot e.g.

  1. Launch librespot in win cmd librespot.exe --name test-libre --verbose --access-token ****
  2. Wait for it to connect and register, find a device id and copy: (e.g. in the line Requesting https://gew4-spclient.spotify.com:443/connect-state/v1/devices/732d5f3b265c469083d7da95c8dbc78a1a2711a3?product=0&country=CZ&salt=1045896257) -> 732d5f3b265c469083d7da95c8dbc78a1a2711a3
  3. Open Spotify Web API start-playback endpoint page, put device id copied above and example body: {"uris":["spotify:track:1ZyQEn0iceHj0Lbt6I6Op3"]}
  4. Observer the error response on the page

Log

I am not sure the full log here is really needed, just copying for now the part of the moment of execution of a command in Web, with several lines before and after.

[2025-06-10T13:12:27Z TRACE librespot_core::dealer] Received pong
[2025-06-10T13:12:57Z TRACE librespot_core::dealer] Sent ping
[2025-06-10T13:12:57Z TRACE librespot_core::dealer] Received pong
[2025-06-10T13:13:27Z TRACE librespot_core::session] Sending Pong
[2025-06-10T13:13:27Z TRACE librespot_core::session] keep-alive state: ExpectingPongAck, timeout in 20.0
[2025-06-10T13:13:27Z TRACE librespot_core::session] Received PongAck
[2025-06-10T13:13:27Z TRACE librespot_core::session] keep-alive state: ExpectingPing, timeout in 80.0
[2025-06-10T13:13:27Z TRACE librespot_core::dealer] Sent ping
[2025-06-10T13:13:27Z TRACE librespot_core::dealer] Received pong
[2025-06-10T13:13:57Z TRACE librespot_core::dealer] Sent ping
[2025-06-10T13:13:57Z TRACE librespot_core::dealer] Received pong
[2025-06-10T13:14:10Z TRACE librespot_core::dealer] dealer request hm://connect-state/v1/player/command
[2025-06-10T13:14:10Z TRACE librespot_core::dealer::protocol] message was sent with gzip encoding
[2025-06-10T13:14:10Z TRACE librespot_core::dealer::protocol] websocket request: Object {
        "command": Object {
            "context": Object {
                "pages": Array [
                    Object {
                        "tracks": Array [
                            Object {
                                "uri": String("spotify:track:1ZyQEn0iceHj0Lbt6I6Op3"),
                            },
                        ],
                    },
                ],
            },
            "endpoint": String("play"),
            "logging_params": Object {
                "device_identifier": String("webapi-cfe923b2d660439caf2b557b21f31221"),
            },
            "options": Object {},
            "play_origin": Object {
                "device_identifier": String("webapi-cfe923b2d660439caf2b557b21f31221"),
            },
        },
        "message_id": Number(1509561780),
        "play_on_secondary_stream": Null,
        "sent_by_device_id": String("webapi-cfe923b2d660439caf2b557b21f31221"),
        "target_alias_id": Number(0),
    }
[2025-06-10T13:14:10Z DEBUG librespot_connect::spirc] handling: 'endpoint: play' from webapi-cfe923b2d660439caf2b557b21f31221
[2025-06-10T13:14:10Z ERROR librespot_connect::spirc] failed to handle request: Service unavailable { context had no uri }
[2025-06-10T13:14:10Z DEBUG librespot_core::dealer::manager] replying to ws request: Failure
[2025-06-10T13:14:27Z TRACE librespot_core::session] Received Ping
[2025-06-10T13:14:27Z TRACE librespot_core::session] keep-alive state: PendingPong, timeout in 60.0
[2025-06-10T13:14:27Z DEBUG librespot_core::session] Session strong=6 weak=7
[2025-06-10T13:14:27Z TRACE librespot_core::dealer] Sent ping
[2025-06-10T13:14:27Z TRACE librespot_core::dealer] Received pong
[2025-06-10T13:14:57Z TRACE librespot_core::dealer] Sent ping
[2025-06-10T13:14:57Z TRACE librespot_core::dealer] Received pong

Host (what you are running librespot on):

  • OS: Microsoft Windows [Version 10.0.22631.5335]

Additional context

If I execute the command, connected to some Spotify client - everything goes smooth, and the musics starts. Switching to Librespot later is going right as well.

Originally created by @maliavko on GitHub (Jun 10, 2025). Original GitHub issue: https://github.com/librespot-org/librespot/issues/1508 ### Description Starting playback from [Spotify Web API](https://developer.spotify.com/documentation/web-api/reference/start-a-users-playback) for several tracks via list of URIs generates an error response, when the current playback device is Librespot. ``` { "error" : { "status" : 403, "message" : "Player command failed: Restriction violated", "reason" : "UNKNOWN" } } ``` If the device is official Spotify desktop client or web-page - everything goes well. Request body example: ``` { "uris":["spotify:track:1ZyQEn0iceHj0Lbt6I6Op3"] } ``` ### Version Built from sources on Windows librespot 0.6.0-dev 8b72954 (Built on 2025-06-02, Build ID: BQcgs54b, Profile: release) ### How to reproduce Steps to reproduce the behavior in *librespot* e.g. 1. Launch `librespot` in win cmd `librespot.exe --name test-libre --verbose --access-token ****` 2. Wait for it to connect and register, find a device id and copy: (e.g. in the line `Requesting https://gew4-spclient.spotify.com:443/connect-state/v1/devices/732d5f3b265c469083d7da95c8dbc78a1a2711a3?product=0&country=CZ&salt=1045896257`) -> `732d5f3b265c469083d7da95c8dbc78a1a2711a3` 3. Open Spotify Web API start-playback endpoint [page](https://developer.spotify.com/documentation/web-api/reference/start-a-users-playback), put device id copied above and example body: `{"uris":["spotify:track:1ZyQEn0iceHj0Lbt6I6Op3"]}` 4. Observer the error response on the page ### Log I am not sure the full log here is really needed, just copying for now the part of the moment of execution of a command in Web, with several lines before and after. ``` [2025-06-10T13:12:27Z TRACE librespot_core::dealer] Received pong [2025-06-10T13:12:57Z TRACE librespot_core::dealer] Sent ping [2025-06-10T13:12:57Z TRACE librespot_core::dealer] Received pong [2025-06-10T13:13:27Z TRACE librespot_core::session] Sending Pong [2025-06-10T13:13:27Z TRACE librespot_core::session] keep-alive state: ExpectingPongAck, timeout in 20.0 [2025-06-10T13:13:27Z TRACE librespot_core::session] Received PongAck [2025-06-10T13:13:27Z TRACE librespot_core::session] keep-alive state: ExpectingPing, timeout in 80.0 [2025-06-10T13:13:27Z TRACE librespot_core::dealer] Sent ping [2025-06-10T13:13:27Z TRACE librespot_core::dealer] Received pong [2025-06-10T13:13:57Z TRACE librespot_core::dealer] Sent ping [2025-06-10T13:13:57Z TRACE librespot_core::dealer] Received pong [2025-06-10T13:14:10Z TRACE librespot_core::dealer] dealer request hm://connect-state/v1/player/command [2025-06-10T13:14:10Z TRACE librespot_core::dealer::protocol] message was sent with gzip encoding [2025-06-10T13:14:10Z TRACE librespot_core::dealer::protocol] websocket request: Object { "command": Object { "context": Object { "pages": Array [ Object { "tracks": Array [ Object { "uri": String("spotify:track:1ZyQEn0iceHj0Lbt6I6Op3"), }, ], }, ], }, "endpoint": String("play"), "logging_params": Object { "device_identifier": String("webapi-cfe923b2d660439caf2b557b21f31221"), }, "options": Object {}, "play_origin": Object { "device_identifier": String("webapi-cfe923b2d660439caf2b557b21f31221"), }, }, "message_id": Number(1509561780), "play_on_secondary_stream": Null, "sent_by_device_id": String("webapi-cfe923b2d660439caf2b557b21f31221"), "target_alias_id": Number(0), } [2025-06-10T13:14:10Z DEBUG librespot_connect::spirc] handling: 'endpoint: play' from webapi-cfe923b2d660439caf2b557b21f31221 [2025-06-10T13:14:10Z ERROR librespot_connect::spirc] failed to handle request: Service unavailable { context had no uri } [2025-06-10T13:14:10Z DEBUG librespot_core::dealer::manager] replying to ws request: Failure [2025-06-10T13:14:27Z TRACE librespot_core::session] Received Ping [2025-06-10T13:14:27Z TRACE librespot_core::session] keep-alive state: PendingPong, timeout in 60.0 [2025-06-10T13:14:27Z DEBUG librespot_core::session] Session strong=6 weak=7 [2025-06-10T13:14:27Z TRACE librespot_core::dealer] Sent ping [2025-06-10T13:14:27Z TRACE librespot_core::dealer] Received pong [2025-06-10T13:14:57Z TRACE librespot_core::dealer] Sent ping [2025-06-10T13:14:57Z TRACE librespot_core::dealer] Received pong ``` ### Host (what you are running `librespot` on): - OS: Microsoft Windows [Version 10.0.22631.5335] ### Additional context If I execute the command, connected to some Spotify client - everything goes smooth, and the musics starts. Switching to Librespot later is going right as well.
kerem 2026-02-27 19:31:56 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@photovoltex commented on GitHub (Jun 10, 2025):

403 usually means that there are missing rights to access the endpoint we want to use internally.

Could you try this again with an access-token generated via login5 or with full scope access?

I will look later into it a bit deeper but an initial check if it's permission or logic related would be nice to know :) Thanks in advance

<!-- gh-comment-id:2959303967 --> @photovoltex commented on GitHub (Jun 10, 2025): 403 usually means that there are missing rights to access the endpoint we want to use internally. Could you try this again with an access-token generated via login5 or with full scope access? I will look later into it a bit deeper but an initial check if it's permission or logic related would be nice to know :) Thanks in advance
Author
Owner

@photovoltex commented on GitHub (Jun 10, 2025):

Tho looking at the log it seems more like an obvious logic error. Probably an assumption that was made incorrectly.

<!-- gh-comment-id:2959418937 --> @photovoltex commented on GitHub (Jun 10, 2025): Tho looking at the log it seems more like an obvious logic error. Probably an assumption that was made incorrectly.
Author
Owner

@photovoltex commented on GitHub (Jun 10, 2025):

It seems to originate from here
https://github.com/librespot-org/librespot/blob/dev/connect%2Fsrc%2Fspirc.rs#L992. It might be that the logic broke while merging a different branch into it.

<!-- gh-comment-id:2959425692 --> @photovoltex commented on GitHub (Jun 10, 2025): It seems to originate from here https://github.com/librespot-org/librespot/blob/dev/connect%2Fsrc%2Fspirc.rs#L992. It might be that the logic broke while merging a different branch into it.
Author
Owner

@maliavko commented on GitHub (Jun 10, 2025):

Hey,

If you mean launching librespot with the --enable-oauth option, so I've just tried, paired the app and provided all the acceses throught the web-form, and result is the same.

I have an app registered on Spotify https://developer.spotify.com/ with access to Web API and Playback API, my app goes through auth flow with the scope (not sure how to generate full-access without specifying full list of accesses):

    scope =
        "streaming "
        "playlist-read-private "
        "playlist-read-collaborative "
        "playlist-modify-private "
        "playlist-modify-public "
        "user-top-read "
        "user-read-email "
        "user-read-private "
        "user-read-playback-state "
        "user-read-recently-played "
        "user-read-currently-playing "
        "user-modify-playback-state "
        "user-follow-read "
        "user-follow-modify "
        "user-library-read "
        "user-library-modify";

... and I hand over the access token into librespot process usually.

For the sake of test I obtained a token from their getting started page with the button "Reveal your access token", and got the same error result.

<!-- gh-comment-id:2959440366 --> @maliavko commented on GitHub (Jun 10, 2025): Hey, If you mean launching librespot with the `--enable-oauth` option, so I've just tried, paired the app and provided all the acceses throught the web-form, and result is the same. I have an app registered on Spotify https://developer.spotify.com/ with access to Web API and Playback API, my app goes through auth flow with the scope (not sure how to generate full-access without specifying full list of accesses): ``` scope = "streaming " "playlist-read-private " "playlist-read-collaborative " "playlist-modify-private " "playlist-modify-public " "user-top-read " "user-read-email " "user-read-private " "user-read-playback-state " "user-read-recently-played " "user-read-currently-playing " "user-modify-playback-state " "user-follow-read " "user-follow-modify " "user-library-read " "user-library-modify"; ``` ... and I hand over the access token into librespot process usually. For the sake of test I obtained a token from their [getting started](https://developer.spotify.com/documentation/web-playback-sdk/tutorials/getting-started) page with the button "Reveal your access token", and got the same error result.
Author
Owner

@photovoltex commented on GitHub (Jun 10, 2025):

Oh xD. A very simple bug which most certainly was created unintentionally while merging^^;

Thanks for the find :D

<!-- gh-comment-id:2959602668 --> @photovoltex commented on GitHub (Jun 10, 2025): Oh xD. A very simple bug which most certainly was created unintentionally while merging^^; Thanks for the find :D
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/librespot#684
No description provided.