What happened
internal/webstream/icy_metadata.go:141 calls p.db.Save(&history) to update the most-recent play_histories row with newly-observed ICY metadata. For webstream rows media_id is the zero string (no associated media file), and Save serializes the whole struct — Postgres rejects the empty string as an invalid uuid:
2026/05/10 07:19:13 /build/internal/webstream/icy_metadata.go:141 ERROR:
invalid input syntax for type uuid: "" (SQLSTATE 22P02)
UPDATE "play_histories" SET … "media_id"='', … WHERE "id" = '16560552-…'
WRN failed to update play history with ICY metadata
error="ERROR: invalid input syntax for type uuid: \"\" (SQLSTATE 22P02)"
component=icy_poller webstream_id=e4fd2190-…
Net effect: the now-playing API never reflects the latest ICY title/artist for webstream-sourced mounts, because every update silently fails.
Root cause
Same class of bug as #(v1.39.16 commit c12545a) which fixed the insert path in director.go with Omit("MediaID"). The Save in icy_metadata.go is the update sibling — it was missed.
Fix
Don't use Save (which writes every column). Use Updates with an explicit map of only the fields the poller is allowed to mutate (artist, title, metadata). That way media_id is left untouched and the empty-uuid string never reaches Postgres.
err := p.db.Model(&history).Updates(map[string]any{
"artist": artist,
"title": title,
"metadata": history.Metadata,
}).Error
Severity
P3 — listener-facing impact is "now-playing metadata stops refreshing on webstreams that emit ICY", which is degraded UX rather than dead air. But it's noisy in the logs and easy to fix.
Repro
Any webstream relay that exposes ICY metadata. Observed on Grim Leftover's (webstream_id=e4fd2190-f62e-444c-9fc4-f0654e03c699) on 2026-05-10 ~07:19 UTC.
What happened
internal/webstream/icy_metadata.go:141callsp.db.Save(&history)to update the most-recentplay_historiesrow with newly-observed ICY metadata. For webstream rowsmedia_idis the zero string (no associated media file), and Save serializes the whole struct — Postgres rejects the empty string as an invalid uuid:Net effect: the now-playing API never reflects the latest ICY title/artist for webstream-sourced mounts, because every update silently fails.
Root cause
Same class of bug as #(v1.39.16 commit c12545a) which fixed the insert path in
director.gowithOmit("MediaID"). The Save inicy_metadata.gois the update sibling — it was missed.Fix
Don't use
Save(which writes every column). UseUpdateswith an explicit map of only the fields the poller is allowed to mutate (artist,title,metadata). That waymedia_idis left untouched and the empty-uuid string never reaches Postgres.Severity
P3 — listener-facing impact is "now-playing metadata stops refreshing on webstreams that emit ICY", which is degraded UX rather than dead air. But it's noisy in the logs and easy to fix.
Repro
Any webstream relay that exposes ICY metadata. Observed on
Grim Leftover's(webstream_id=e4fd2190-f62e-444c-9fc4-f0654e03c699) on 2026-05-10 ~07:19 UTC.