d2lang/d2 · error
failed to decompress: %w
Error message
failed to decompress: %w
What it means
DecompressBrotli feeds compressed bytes through a brotli reader and returns this wrapped error if io.ReadAll fails mid-stream. It indicates the input is not valid brotli data or the stream is truncated/corrupt.
Source
Thrown at lib/compression/brotli.go:17
// d2 uses compression for compressing large static assets when its built into WASM for d2.js
package compression
import (
"bytes"
"fmt"
"io"
"github.com/andybalholm/brotli"
)
func DecompressBrotli(compressed []byte) (string, error) {
reader := brotli.NewReader(bytes.NewReader(compressed))
decompressed, err := io.ReadAll(reader)
if err != nil {
return "", fmt.Errorf("failed to decompress: %w", err)
}
return string(decompressed), nil
}
View on GitHub (pinned to 0d69dca6f5)
Solutions
- Verify the input was compressed with brotli (CompressBrotli) and not gzip/zlib/base64-encoded again
- Check the payload wasn't truncated (compare lengths/hashes with the source)
- Test round-trip: compress with the same lib then decompress to isolate corruption
- Wrap the call so callers see the underlying brotli error via %w for diagnosis
Defensive patterns
Strategy: validation
Validate before calling
if len(compressed) == 0 {
return errors.New("empty payload, not brotli data")
}
if compressed[0] != 0x1b && (compressed[0]&0x01) == 0 {
return fmt.Errorf("first byte %#x does not look like brotli", compressed[0])
} Type guard
func looksLikeBrotli(b []byte) bool {
// brotli streams start with WBITS; simple sanity: non-empty and not ASCII text
return len(b) > 0 && b[0] != '<' && b[0] != '{' && b[0] != 'H'
} Try / catch
out, err := compression.DecompressBrotli(data)
if err != nil {
var brErr brotli.Error
if errors.As(err, &brErr) {
log.Printf("brotli corruption: %v", brErr)
}
return err
} Prevention
- Round-trip test payloads with CompressBrotli/DecompressBrotli at write time
- Do not re-encode brotli bytes (e.g. base64) without decoding before decompression
- Store payloads with integrity checks (length/hash) to detect truncation
When it happens
Trigger: Calling DecompressBrotli with bytes that are not brotli-compressed (plain text, gzip, base64 still encoded), or a truncated brotli stream.
Common situations: Decoding embedded/compressed diagram links where the payload was double-encoded, corrupted in transit/storage, or produced by a different compression algorithm.
Related errors
- failed to decode %q response for %s: %w
- unsupported content encoding %q
- Failed to decompress SourceSansPro-Regular: %v
- Failed to decompress SourceSansPro-Bold: %v
- Failed to decompress SourceSansPro-Semibold: %v
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/5ed4bc1ff9100056.
Report an issue: GitHub.