[GH-ISSUE #97] panic: invalid uri: when prefetching a track #67

Closed
opened 2026-02-28 14:25:06 +03:00 by kerem · 3 comments
Owner

Originally created by @aykevl on GitHub (Sep 19, 2024).
Original GitHub issue: https://github.com/devgianlu/go-librespot/issues/97

In some circumstances (not yet sure when this happens but it seems to have something to do with playing whole albums), next.Uri is an empty string here:

github.com/devgianlu/go-librespot@b95e6acdcc/cmd/daemon/controls.go (L25)

This leads to a crash:

github.com/devgianlu/go-librespot@b95e6acdcc/ids.go (L110-L114)

The next object in this case looks like this:

&connectstate.ContextTrack{state:impl.MessageState{NoUnkeyedLiterals:pragma.NoUnkeyedLiterals{}, DoNotCompare:pragma.DoNotCompare{}, DoNotCopy:pragma.DoNotCopy{}, atomicMessageInfo:(*impl.MessageInfo)(nil)}, sizeCache:0, unknownFields:[]uint8(nil), Uri:"", Uid:"a1e0611f0a14df708f14", Gid:[]uint8{0x7, 0x7d, 0x48, 0x4f, 0x2c, 0x99, 0x4d, 0x24, 0x93, 0xcf, 0x57, 0x1, 0xfd, 0x71, 0xd7, 0x31}, Metadata:map[string]string{"context_uri":"spotify:album:0tiOfqFu4d3UJ2r1LsoG3Z", "entity_uri":"spotify:album:0tiOfqFu4d3UJ2r1LsoG3Z"}}

If you look into it, there's an album ID ("entity_uri":"spotify:album:0tiOfqFu4d3UJ2r1LsoG3Z"), and something that looks like a track ID (Uid:"a1e0611f0a14df708f14"). So it looks like there's enough information to prefetch this track, but I'm not entirely sure how to implement it.
(Interestingly this only happens while prefetching, perhaps the code that pulls the track ID when actually playing a track takes care of this case? In which case it would make sense to generalize that code and use it in both places).

Originally created by @aykevl on GitHub (Sep 19, 2024). Original GitHub issue: https://github.com/devgianlu/go-librespot/issues/97 In some circumstances (not yet sure when this happens but it seems to have something to do with playing whole albums), `next.Uri` is an empty string here: https://github.com/devgianlu/go-librespot/blob/b95e6acdcc266e0b54234c0c98ffd3bd6395f9d1/cmd/daemon/controls.go#L25 This leads to a crash: https://github.com/devgianlu/go-librespot/blob/b95e6acdcc266e0b54234c0c98ffd3bd6395f9d1/ids.go#L110-L114 The `next` object in this case looks like this: ```go &connectstate.ContextTrack{state:impl.MessageState{NoUnkeyedLiterals:pragma.NoUnkeyedLiterals{}, DoNotCompare:pragma.DoNotCompare{}, DoNotCopy:pragma.DoNotCopy{}, atomicMessageInfo:(*impl.MessageInfo)(nil)}, sizeCache:0, unknownFields:[]uint8(nil), Uri:"", Uid:"a1e0611f0a14df708f14", Gid:[]uint8{0x7, 0x7d, 0x48, 0x4f, 0x2c, 0x99, 0x4d, 0x24, 0x93, 0xcf, 0x57, 0x1, 0xfd, 0x71, 0xd7, 0x31}, Metadata:map[string]string{"context_uri":"spotify:album:0tiOfqFu4d3UJ2r1LsoG3Z", "entity_uri":"spotify:album:0tiOfqFu4d3UJ2r1LsoG3Z"}} ``` If you look into it, there's an album ID (`"entity_uri":"spotify:album:0tiOfqFu4d3UJ2r1LsoG3Z"`), and something that looks like a track ID (`Uid:"a1e0611f0a14df708f14"`). So it looks like there's enough information to prefetch this track, but I'm not entirely sure how to implement it. (Interestingly this only happens while prefetching, perhaps the code that pulls the track ID when actually playing a track takes care of this case? In which case it would make sense to generalize that code and use it in both places).
kerem 2026-02-28 14:25:06 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@gregnebu commented on GitHub (Sep 20, 2024):

+1 I faced the same yesterday, and came to the same ccl. Unfortunately I'm not familiar enough with the code base to indeed suggest a good fix

<!-- gh-comment-id:2363070426 --> @gregnebu commented on GitHub (Sep 20, 2024): +1 I faced the same yesterday, and came to the same ccl. Unfortunately I'm not familiar enough with the code base to indeed suggest a good fix
Author
Owner

@aykevl commented on GitHub (Sep 20, 2024):

I have a fix at #98, but have a hard time verifying whether it works as expected (since it happens so rarely). If you know how to reproduce the issue, you can put some logging in the else case here to see whether it is triggered and whether it works correctly:

	if next.Uri != "" {
		nextId = librespot.SpotifyIdFromUri(next.Uri)
	} else {
		nextId = librespot.SpotifyIdFromGid(librespot.SpotifyIdTypeTrack, next.Gid)
	}
<!-- gh-comment-id:2363586258 --> @aykevl commented on GitHub (Sep 20, 2024): I have a fix at #98, but have a hard time verifying whether it works as expected (since it happens so rarely). If you know how to reproduce the issue, you can put some logging in the `else` case here to see whether it is triggered and whether it works correctly: ```go if next.Uri != "" { nextId = librespot.SpotifyIdFromUri(next.Uri) } else { nextId = librespot.SpotifyIdFromGid(librespot.SpotifyIdTypeTrack, next.Gid) } ```
Author
Owner

@aykevl commented on GitHub (Oct 3, 2024):

#110 avoids the panic. It still won't prefetch, but that only means the next track will have a slight delay before it starts. That's much better than panicking.

I think it works well enough for now.

<!-- gh-comment-id:2392484316 --> @aykevl commented on GitHub (Oct 3, 2024): #110 avoids the panic. It still won't prefetch, but that only means the next track will have a slight delay before it starts. That's much better than panicking. I think it works well enough for now.
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/go-librespot#67
No description provided.