diff --git a/internal/handlers/media.go b/internal/handlers/media.go index 6a1631d7..ec9365ce 100644 --- a/internal/handlers/media.go +++ b/internal/handlers/media.go @@ -1610,6 +1610,14 @@ func (mh *MediaHandler) UpdateMediaItem(c *echo.Context) error { Summary: pgtype.Text{String: req.Summary, Valid: req.Summary != ""}, } + // audio_metadata is scan-owned (track manifest, chapters, duration) + // and has no editor field: the full-row update writes it + // unconditionally, so an unguarded save NULLed every audiobook's + // payload — books dropped back to "1 second long" on a plain + // metadata edit (2026-10-21 incident class). Write-after-success: + // carry the existing bytes; only the audio chain replaces them. + params.AudioMetadata = existing.AudioMetadata + // Fields the user actually changed become overrides so future scans keep // the custom values. An explicit cover upload/removal always overrides. overrides := utils.DetectMetadataOverrides(params, existing)