sqshq/sampler · critical
panic(err)
Error message
panic(err)
What it means
AudioPlayer.Beep panics if constructing the mp3.Decoder from the embedded beep asset fails — the bundled MP3 bytes cannot be parsed (truncated, wrong format, or corrupt embedded asset). This is a hard panic by design because a failed beep indicates a broken build embedding of assets.
Source
Thrown at asset/player.go:41
if err != nil {
// it is expected to fail when some of the system
// libraries are not available (e.g. libasound2)
// it is not the main functionality of the application,
// so we allow startup in no-sound mode
return nil
}
return &AudioPlayer{
player: player,
beep: bytes,
}
}
func (a *AudioPlayer) Beep() {
decoder, err := mp3.NewDecoder(NewAssetFile(a.beep))
if err != nil {
panic(err)
}
if _, err := io.Copy(a.player, decoder); err != nil {
panic(err)
}
}
func (a *AudioPlayer) Close() {
_ = a.player.Close()
}
View on GitHub (pinned to 9bc7ba732d)
Solutions
- Restore the original, valid MP3 asset and rebuild (verify go:embed includes the file)
- Regenerate/re-embed the beep asset and confirm mp3.NewDecoder succeeds in a unit test
- Wrap Beep with recover() if a missing sound should not crash the app, and log instead of panicking
- Verify the binary actually embeds assets (rebuild without -trimpath tricks that might affect embed paths)
Example fix
// before
func (a *AudioPlayer) Beep() {
decoder, err := mp3.NewDecoder(NewAssetFile(a.beep))
if err != nil {
panic(err)
}
// after
func (a *AudioPlayer) Beep() (err error) {
defer func() { if r := recover(); r != nil { err = fmt.Errorf("beep failed: %v", r) } }()
decoder, derr := mp3.NewDecoder(NewAssetFile(a.beep))
if derr != nil { return derr } Defensive patterns
Strategy: try-catch
Validate before calling
// pre-validate embedded asset
f, err := asset.Asset("beep.mp3")
if err != nil || len(f) < 4 { audioDisabled = true } Type guard
func audioAvailable() bool { data, err := asset.Asset("beep.mp3"); return err == nil && len(data) > 0 } Try / catch
func safeBeep(p *asset.AudioPlayer) {
defer func() { if r := recover(); r != nil { log.Printf("beep skipped: %v", r) } }()
p.Beep()
} Prevention
- Add a startup self-test that decodes the beep asset once
- Keep embedded MP3 assets intact through build/bundle steps
- Treat sound as optional and recover from panics
When it happens
Trigger: Calling Execute (which calls Beep) when NewAssetFile(a.beep) yields data that mp3.NewDecoder rejects — e.g. asset embedding changed, file replaced with non-MP3 content, or empty asset.
Common situations: Custom builds where go:embed assets were modified or regenerated incorrectly; stripped binaries missing embedded assets; corrupted resource after bundling/packing.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Failed to load the font:
- Failed to find component type %v with title %v
- Specified theme is not supported: %v
- errorText.String()
- PTY mode is not supported on Windows
AI-assisted analysis of sqshq/sampler@9bc7ba732d (2026-09-06).
Data as JSON: /api/errors/38d4a20b39b3dbaa.
Report an issue: GitHub.