Skip to content

Subsonic playlist song-attach params are unreachable — serde_urlencoded cannot deserialize Vec query fields #477

Description

@forkwright

Finding

The Subsonic createPlaylist / updatePlaylist endpoints accept repeated multi-value query parameters (songId, songIdToAdd, songIndexToRemove) that deserialize into Vec<String>. But axum 0.8's Query extractor uses serde_urlencoded 0.7.1, which cannot populate a Vec field from a query string at all. Every form fails: songId=x errors invalid type: string, expected a sequence; repeated keys songId=x&songId=y error identically; songId[]=x deserializes to None. So any real OpenSubsonic client that attaches songs to a playlist receives a 400 at query-parse and can never reach the handler.

Evidence

crates/paroche/src/subsonic/playlists.rs — the create_playlist / update_playlist handlers take Query<...> params with Vec<String> song fields. Confirmed empirically against serde_urlencoded 0.7.1 (axum 0.8 Query): no query-string shape populates the Vec. Surfaced while writing the #457 transaction-rollback tests — the song-insert loop is not drivable through the HTTP surface, so the create-path track-rollback could only be proven via a reachable sibling path.

Why this matters

Attaching songs to a playlist is core OpenSubsonic functionality. It is currently broken end-to-end for every client, independent of the transaction fix in #457 (which is correct-by-construction but only independently HTTP-testable on the metadata path).

Desired correction

Swap the query extractor for one that supports sequences — e.g. serde_html_form (a drop-in Query-shaped extractor that handles repeated keys) — across the Subsonic handlers that take repeated params. Audit the whole subsonic/ tree for other Vec-valued Query fields silently suffering the same fate.

Done when: createPlaylist/updatePlaylist with repeated songId/songIdToAdd actually attach the songs, proven by a test driving the real HTTP query surface (not a direct handler call); no Vec-valued Subsonic query param is left on the broken extractor.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions