{"record":{"id":"f2db59748afe88fb","repo":"d2lang/d2","slug":"failed-to-decompress-sourcecodepro-italic-v","errorCode":null,"errorMessage":"Failed to decompress SourceCodePro-Italic: %v","messagePattern":"Failed to decompress SourceCodePro-Italic: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"d2renderers/d2fonts/d2fonts_embed_wasm.go","lineNumber":98,"sourceCode":"\t\tpanic(fmt.Sprintf(\"Failed to decompress SourceCodePro-Regular: %v\", err))\n\t} else {\n\t\tFontEncodings.Set(Font{Family: SourceCodePro, Style: FONT_STYLE_REGULAR}, str)\n\t}\n\n\tif str, err := compression.DecompressBrotli(sourceCodeProBoldBr); err != nil {\n\t\tpanic(fmt.Sprintf(\"Failed to decompress SourceCodePro-Bold: %v\", err))\n\t} else {\n\t\tFontEncodings.Set(Font{Family: SourceCodePro, Style: FONT_STYLE_BOLD}, str)\n\t}\n\n\tif str, err := compression.DecompressBrotli(sourceCodeProSemiboldBr); err != nil {\n\t\tpanic(fmt.Sprintf(\"Failed to decompress SourceCodePro-Semibold: %v\", err))\n\t} else {\n\t\tFontEncodings.Set(Font{Family: SourceCodePro, Style: FONT_STYLE_SEMIBOLD}, str)\n\t}\n\n\tif str, err := compression.DecompressBrotli(sourceCodeProItalicBr); err != nil {\n\t\tpanic(fmt.Sprintf(\"Failed to decompress SourceCodePro-Italic: %v\", err))\n\t} else {\n\t\tFontEncodings.Set(Font{Family: SourceCodePro, Style: FONT_STYLE_ITALIC}, str)\n\t}\n\n\t// Decompress and register FuzzyBubbles fonts\n\tif str, err := compression.DecompressBrotli(fuzzyBubblesRegularBr); err != nil {\n\t\tpanic(fmt.Sprintf(\"Failed to decompress FuzzyBubbles-Regular: %v\", err))\n\t} else {\n\t\tFontEncodings.Set(Font{Family: HandDrawn, Style: FONT_STYLE_REGULAR}, str)\n\t\t// HandDrawn has no italic, so reuse regular\n\t\tFontEncodings.Set(Font{Family: HandDrawn, Style: FONT_STYLE_ITALIC}, str)\n\t}\n\n\tif str, err := compression.DecompressBrotli(fuzzyBubblesBoldBr); err != nil {\n\t\tpanic(fmt.Sprintf(\"Failed to decompress FuzzyBubbles-Bold: %v\", err))\n\t} else {\n\t\tFontEncodings.Set(Font{Family: HandDrawn, Style: FONT_STYLE_BOLD}, str)\n\t\t// HandDrawn has no semibold, so reuse bold","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2renderers/d2fonts/d2fonts_embed_wasm.go#L80-L116","documentation":"At WASM build init, d2fonts decompresses embedded Brotli-compressed font blobs and registers them in FontEncodings. If compression.DecompressBrotli fails for the embedded SourceCodePro-Italic blob, init panics with this message. It means the embedded asset is corrupt/truncated or the brotli decompressor failed.","triggerScenarios":"Process start of a WASM build: init in d2renderers/d2fonts/d2fonts_embed_wasm.go:98 calls compression.DecompressBrotli(sourceCodeProItalicBr) and the returned err is non-nil — the embedded brotli bytes are corrupted, truncated, or were replaced with invalid data at build time.","commonSituations":"Custom builds where embedded font assets were regenerated incorrectly; file corruption or truncation of the .br assets; build tooling (go:embed/generate steps) producing bad blobs; memory pressure in tiny WASM environments causing decompression failure.","solutions":["Rebuild the binary/WASM module from a clean checkout so the embedded brotli assets are regenerated","Verify the sourceCodeProItalicBr embedded blob is a valid, uncorrupted .br file (test-decompress it independently)","Replace or re-download the corrupted SourceCodePro-Italic .br asset, then rebuild","Ensure the brotli decompression dependency version matches the compression level used to produce the assets"],"exampleFix":"// before (corrupted blob in source tree)\nfonts/sourceCodePro-Italic.ttf.br // truncated file\n// after\ncurl -O <valid sourceCodePro-Italic.ttf.br> && go build","handlingStrategy":"try-catch","validationCode":"// Go has no try before init; validate assets at build time:\n// go run ./tools/verify-brotli-assets d2renderers/d2fonts/assets/sourceCodePro-Italic.ttf.br\nfunc validBrotli(b []byte) bool { _, err := compression.DecompressBrotli(b); return err == nil }","typeGuard":null,"tryCatchPattern":"// Go: init panics cannot be caught; guard at embedding site\nfunc mustDecomp(b []byte, name string) string {\n    s, err := compression.DecompressBrotli(b)\n    if err != nil { log.Fatalf(\"font asset %s invalid: %v\", name, err) }\n    return s\n}","preventionTips":["CI check: decompress every embedded .br font asset before build","Rebuild from clean checkouts; never hand-edit .br blobs","Pin the brotli encoder/decoder library versions used by the asset pipeline"],"tags":["go","panic","init","wasm","brotli","embedded-assets"],"backgroundTag":"brotli-decompression-failed","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}