d2lang/d2 · critical
Failed to decompress FuzzyBubbles-Regular: %v
Error message
Failed to decompress FuzzyBubbles-Regular: %v
What it means
During WASM init, d2fonts decompresses the embedded FuzzyBubbles-Regular brotli blob to register the HandDrawn regular (and italic fallback) font. Failure decompressing that blob panics init with this message. The font is embedded at build time, so failures indicate bad/corrupt embedded data rather than user input.
Source
Thrown at d2renderers/d2fonts/d2fonts_embed_wasm.go:105
} else {
FontEncodings.Set(Font{Family: SourceCodePro, Style: FONT_STYLE_BOLD}, str)
}
if str, err := compression.DecompressBrotli(sourceCodeProSemiboldBr); err != nil {
panic(fmt.Sprintf("Failed to decompress SourceCodePro-Semibold: %v", err))
} else {
FontEncodings.Set(Font{Family: SourceCodePro, Style: FONT_STYLE_SEMIBOLD}, str)
}
if str, err := compression.DecompressBrotli(sourceCodeProItalicBr); err != nil {
panic(fmt.Sprintf("Failed to decompress SourceCodePro-Italic: %v", err))
} else {
FontEncodings.Set(Font{Family: SourceCodePro, Style: FONT_STYLE_ITALIC}, str)
}
// Decompress and register FuzzyBubbles fonts
if str, err := compression.DecompressBrotli(fuzzyBubblesRegularBr); err != nil {
panic(fmt.Sprintf("Failed to decompress FuzzyBubbles-Regular: %v", err))
} else {
FontEncodings.Set(Font{Family: HandDrawn, Style: FONT_STYLE_REGULAR}, str)
// HandDrawn has no italic, so reuse regular
FontEncodings.Set(Font{Family: HandDrawn, Style: FONT_STYLE_ITALIC}, str)
}
if str, err := compression.DecompressBrotli(fuzzyBubblesBoldBr); err != nil {
panic(fmt.Sprintf("Failed to decompress FuzzyBubbles-Bold: %v", err))
} else {
FontEncodings.Set(Font{Family: HandDrawn, Style: FONT_STYLE_BOLD}, str)
// HandDrawn has no semibold, so reuse bold
FontEncodings.Set(Font{Family: HandDrawn, Style: FONT_STYLE_SEMIBOLD}, str)
}
// Trim trailing newlines
trimEncodings()
// Initialize FontFaces with TTF filesView on GitHub (pinned to 0d69dca6f5)
Solutions
- Rebuild from a clean checkout to regenerate/restore the embedded fuzzyBubblesRegular blob
- Verify fuzzyBubblesRegularBr decompresses standalone (brotli -d) and replace it if corrupt
- Re-encode the FuzzyBubbles-Regular TTF to brotli with the same encoder settings the project uses
- Check that the compression package's brotli decoder version is compatible with the asset encoder
Example fix
// before fuzzyBubbles-regular.ttf.br // empty/invalid // after brotli -f fuzzyBubbles-regular.ttf && go build ./...
Defensive patterns
Strategy: validation
Validate before calling
// Validate embedded asset pre-build
import "os/exec"
out, err := exec.Command("brotli", "-d", "-c", "fuzzyBubbles-regular.ttf.br").Output()
if err != nil || len(out) == 0 { panic("fuzzyBubbles-regular.ttf.br is corrupt") } Prevention
- Run asset integrity tests in CI (decompress all embedded blobs)
- Regenerate .br assets only with the project's documented pipeline
- Verify file sizes/checksums after merges involving font assets
When it happens
Trigger: Process start of a WASM build: init at d2renderers/d2fonts/d2fonts_embed_wasm.go:105 calls compression.DecompressBrotli(fuzzyBubblesRegularBr) and gets a non-nil error — corrupt, truncated, or invalid embedded brotli data.
Common situations: Regenerating embedded font assets with wrong compression settings; corrupted repo files; build pipeline substituting placeholder/empty blobs; incompatibility between brotli encoder and decoder versions.
Related errors
- Failed to decompress SourceCodePro-Italic: %v
- Failed to decompress FuzzyBubbles-Bold: %v
- Failed to decompress paper texture: %v
- Failed to initialize font faces: %v
- failed to decode %q response for %s: %w
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/5f8525a5ece1ccc1.
Report an issue: GitHub.