d2lang/d2 · critical
Failed to decompress FuzzyBubbles-Bold: %v
Error message
Failed to decompress FuzzyBubbles-Bold: %v
What it means
During WASM init, d2fonts decompresses the embedded FuzzyBubbles-Bold brotli blob to register the HandDrawn bold (and semibold fallback) font. If compression.DecompressBrotli fails, init panics with this message. This is an embedded-asset integrity failure, not a runtime API misuse.
Source
Thrown at d2renderers/d2fonts/d2fonts_embed_wasm.go:113
}
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 files
if err := initializeFontFaces(fontFacesFS); err != nil {
panic(fmt.Sprintf("Failed to initialize font faces: %v", err))
}
}
// trimEncodings removes trailing newlines from all font encodings
func trimEncodings() {
FontEncodings.Range(func(k Font, v string) bool {View on GitHub (pinned to 0d69dca6f5)
Solutions
- Rebuild from a clean checkout so the embedded fuzzyBubblesBold blob is intact
- Verify the .br blob decompresses standalone and replace it if corrupt
- Regenerate the brotli asset from the FuzzyBubbles-Bold TTF using the project's asset pipeline
- Align the brotli library versions used for encoding assets and decoding at runtime
Example fix
// before fuzzyBubbles-bold.ttf.br // truncated git checkout -- d2renderers/d2fonts/assets/ // after git checkout -- d2renderers/d2fonts/assets/ && go build
Defensive patterns
Strategy: validation
Validate before calling
// Pre-build integrity check
b, _ := os.ReadFile("d2renderers/d2fonts/assets/fuzzyBubbles-bold.ttf.br")
if _, err := compression.DecompressBrotli(b); err != nil {
panic("fuzzyBubbles-bold.ttf.br is corrupt: " + err.Error())
} Prevention
- Checksum-verify .br assets in CI
- Avoid partial checkouts/submodule drift; use clean builds
- Document and reuse the single asset-compression script
When it happens
Trigger: Process start of a WASM build: init at d2renderers/d2fonts/d2fonts_embed_wasm.go:113 calls compression.DecompressBrotli(fuzzyBubblesBoldBr) and the error is non-nil — corrupt, truncated, or invalid brotli bytes in the embedded asset.
Common situations: Corrupted repository asset after bad merge/checkout; build step that regenerates .br assets failing silently; encoder/decoder version mismatch; disk or VCS truncation of the blob.
Related errors
- Failed to decompress SourceCodePro-Italic: %v
- Failed to decompress FuzzyBubbles-Regular: %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/60c3a5c23dd0461d.
Report an issue: GitHub.