"Requested entity was not found" when Selecting "Recommended Song" from Playlist
Description
Songs from the "Recommended Songs" list on the bottom of a playlist in Spotify do not play. Instead the current song continues to play and the following error is emitted in the logs:
[2025-03-31T21:34:47Z WARN librespot_connect::state::context] couldn't load context info because: context is not available. type: Default
[2025-03-31T21:34:47Z ERROR librespot_connect::spirc] Requested entity was not found { Response status code: 404 Not Found }
Version
Dev branch: 5981b88ac50876d86c882c2cf817dfe1d0427208
How to reproduce
Steps to reproduce the behavior in librespot e.g.
- Launch
librespotin release mode with no additional parameters except "--name" - Connect with Spotify Connect on iPhone Spotify app (Have not tested on android)
- In the client, select a playlist and play from the playlist
- Then, scroll to bottom and select a song from the "Recommended Songs" section
- Selected song does not play
Log
2025-03-31T21:45:15Z TRACE librespot_core::dealer] dealer request hm://connect-state/v1/player/command
[2025-03-31T21:45:15Z TRACE librespot_core::dealer::protocol] message was sent with gzip encoding
[2025-03-31T21:45:15Z TRACE librespot_core::dealer::protocol] websocket request: Object {
"command": Object {
"context": Object {
"pages": Array [
Object {
"tracks": Array [
Object {
"metadata": Object {
"album_uri": String("spotify:album:5n1GSzC1Reao29ScnpLYqp"),
"artist_uri": String("spotify:artist:46SHBwWsqBkxI7EeeBEQG7"),
},
"uri": String("spotify:track:0FZ4Dmg8jJJAPJnvBIzD9z"),
},
Object {
"metadata": Object {
"album_uri": String("spotify:album:5xqQtdlJUY7Fg4BMp13LrX"),
"artist_uri": String("spotify:artist:13y7CgLHjMVRMDqxdx0Xdo"),
},
"uri": String("spotify:track:2G1tXoGBaEMJ7FKGnkf6ud"),
},
Object {
"metadata": Object {
"album_uri": String("spotify:album:185Tm1g5U7eMOrm3m9SQUh"),
"artist_uri": String("spotify:artist:5K4W6rqBFWDnAN6FQUkS6x"),
},
"uri": String("spotify:track:4S8d14HvHb70ImctNgVzQQ"),
},
Object {
"metadata": Object {
"album_uri": String("spotify:album:6eDx949ONWDCN0O22wFZf7"),
"artist_uri": String("spotify:artist:7iZtZyCzp3LItcw1wtPI3D"),
},
"uri": String("spotify:track:4scpF6J5uMBvoh6sFB7EL1"),
},
Object {
"metadata": Object {
"album_uri": String("spotify:album:3XzSOIE6zGLliuqsVGLmUc"),
"artist_uri": String("spotify:artist:6l3HvQ5sa6mXTsMTB19rO5"),
},
"uri": String("spotify:track:2JvzF1RMd7lE3KmFlsyZD8"),
},
Object {
"metadata": Object {
"album_uri": String("spotify:album:4skCiJhVVSKrDOBtoFbsxU"),
"artist_uri": String("spotify:artist:1URnnhqYAYcrqrcwql10ft"),
},
"uri": String("spotify:track:5eqK0tbzUPo2SoeZsov04s"),
},
],
},
],
"restrictions": Object {},
"uri": String("spotify:playlist:2qpxItBk6JNs887RX4Gj4B:recommended"),
},
"endpoint": String("play"),
"logging_params": Object {
"command_id": String("0f3561af36628f05e54ba7e7abee3469"),
"command_initiated_time": Number(1743457515676),
"command_received_time": Number(1743457515677),
"device_identifier": String("be3cf1920f351ab522e907f167ab026490321a63"),
"interaction_ids": Array [
String("2685BC16-2D7F-45E9-BA9E-20A271D9ABC8"),
],
"page_instance_ids": Array [
String("E46921E0-94BA-4134-AF00-7421B7BAE1D2"),
],
},
"options": Object {
"always_play_something": Bool(false),
"audio_stream": String("default"),
"initially_paused": Bool(false),
"license": String("premium"),
"player_options_override": Object {
"repeating_context": Bool(false),
"shuffling_context": Bool(false),
},
"prefetch_level": String("none"),
"session_id": String(""),
"skip_to": Object {
"track_index": Number(1),
},
"suppressions": Object {},
"system_initiated": Bool(false),
},
"play_options": Object {
"only_for_local_device": Bool(false),
"operation": String("replace"),
"override_restrictions": Bool(false),
"reason": String("interactive"),
"system_initiated": Bool(false),
"trigger": String("immediately"),
},
"play_origin": Object {
"device_identifier": String("be3cf1920f351ab522e907f167ab026490321a63"),
"feature_identifier": String("playlist"),
"feature_version": String("9.0.30.604"),
"referrer_identifier": String("home"),
"view_uri": String("spotify:playlist:2qpxItBk6JNs887RX4Gj4B"),
},
},
"message_id": Number(1848278012),
"play_on_secondary_stream": Null,
"sent_by_device_id": String("be3cf1920f351ab522e907f167ab026490321a63"),
"target_alias_id": Null,
}
[2025-03-31T21:45:15Z DEBUG librespot_connect::spirc] handling: 'endpoint: play' from be3cf1920f351ab522e907f167ab026490321a63
[2025-03-31T21:45:15Z WARN librespot_connect::state::context] couldn't load context info because: context is not available. type: Default
[2025-03-31T21:45:15Z WARN librespot_connect::state::context] couldn't load context info because: context is not available. type: Default
[2025-03-31T21:45:15Z DEBUG librespot_connect::spirc] resolving context for load command
[2025-03-31T21:45:15Z TRACE librespot_connect::context_resolver] added spotify:playlist:2qpxItBk6JNs887RX4Gj4B:recommended to resolver queue
[2025-03-31T21:45:15Z DEBUG librespot_core::http_client] Requesting https://guc3-spclient.spotify.com:443/context-resolve/v1/spotify:playlist:2qpxItBk6JNs887RX4Gj4B:recommended
[2025-03-31T21:45:15Z ERROR librespot_connect::spirc] Requested entity was not found { Response status code: 404 Not Found }
[2025-03-31T21:45:15Z DEBUG librespot_connect::spirc] play track <Some(Index(1))>
[2025-03-31T21:45:15Z DEBUG librespot_connect::spirc] loading with shuffle: <false>, repeat track: <false> context: <false>
[2025-03-31T21:45:15Z ERROR librespot_connect::spirc] failed to handle request: Invalid state { context is not available. type: Default }
[2025-03-31T21:45:15Z DEBUG librespot_core::dealer::manager] replying to ws request: Failure
Host (what you are running librespot on):
- OS: Linux Ubuntu 22.04
- Platform: Lenovo T14
Additional context
n/a
Right... that feature... Yeah I didn't implement that during the rework. There were just too many open questions and the PR back then was oversized enough.
But it seems spotify sends 6 tracks with the request. How many recommended songs were displayed to you?
We might be able to load the given tracks. The question then would become, how we resume after these are done playing? I would assume it continues playing, but from which context? Or do we just switch to autoplay?
That sounds about right. 6 songs showed in the recommended songs list for me.
As for the context, the behavior on the phone is that the 6 songs are considered "Playing from playlist" according to the header on top of the player. Once we've exhausted the 6 songs that where queued from the playlist's recommended songs, it continues playing with a new track that's not from the playlist or the recommended songs and the header on top of the player states that it's "Playing from recommended tracks" which I assume is autoplay.
I suppose if we just handle the tracks and then transition into autoplay that should be relatively simple to implement. There needs to be some adjustments to the current play request, but besides that it should be relatively simple.