dagger/dagger · error
decode length: varint overflow
Error message
decode length: varint overflow
What it means
rowDecoder.length returns this when binary.Uvarint returns n<0, meaning the length varint exceeds its maximum byte width (malformed encoding, more than 10 bytes). The bytes at the offset are not a valid unsigned varint, so the row data or the decode offset is wrong.
Source
Thrown at engine/clientdb/store_codec.go:99
v := d.buf[d.off]
d.off++
switch v {
case 0:
return false, nil
case 1:
return true, nil
default:
return false, fmt.Errorf("decode bool: invalid value %d", v)
}
}
func (d *rowDecoder) length() (int, error) {
v, n := binary.Uvarint(d.buf[d.off:])
if n == 0 {
return 0, fmt.Errorf("decode length: truncated varint")
}
if n < 0 {
return 0, fmt.Errorf("decode length: varint overflow")
}
d.off += n
if v > uint64(maxInt) {
return 0, fmt.Errorf("decode length: %d overflows int", v)
}
return int(v), nil
}
func (d *rowDecoder) take(n int) ([]byte, error) {
if n < 0 || n > len(d.buf)-d.off {
return nil, fmt.Errorf("decode field of length %d: only %d bytes remain", n, len(d.buf)-d.off)
}
v := d.buf[d.off : d.off+n]
d.off += n
return v, nil
}
func (d *rowDecoder) string() (string, error) {View on GitHub (pinned to 82ba2681db)
Solutions
- Compare decoder field order/types with the encoder byte-for-byte; fix any swapped or missing fields.
- Remember binary.Varint (signed, for int64) and binary.Uvarint (unsigned, for lengths) are different encodings — ensure lengths are written with PutUvarint.
- Hex-dump the row and decode by hand to confirm whether the offset or the data is at fault.
- Add a per-row checksum so malformed encodings are rejected at load time instead of mid-decode.
Example fix
// before binary.PutVarint(buf, int64(len(s))) // signed varint for a length // after binary.PutUvarint(buf, uint64(len(s))) // lengths must use Uvarint
Defensive patterns
Strategy: validation
Validate before calling
if _, n := binary.Uvarint(buf[off:]); n < 0 {
return fmt.Errorf("malformed length varint at offset %d", off)
} Try / catch
n, err := dec.length()
if err != nil {
return nil, fmt.Errorf("bad length prefix: %w", err)
} Prevention
- Write length prefixes with binary.PutUvarint (unsigned), not PutVarint.
- Match decoder reads to encoder writes field-for-field.
- Version-stamp rows to prevent cross-version misdecoding.
When it happens
Trigger: rowDecoder.string/bytes decoding a row where the length-prefix position holds non-varint bytes — wrong field order in the decoder, decoding a bytes field where an int64 (signed varint, different encoding) was written, or corrupt data.
Common situations: Writer/reader codec drift (field types swapped between versions); misaligned offset from an earlier field decoded with the wrong width; damaged local trace store.
Related errors
- decode int64: truncated varint
- decode int64: varint overflow
- decode length: truncated varint
- decode bool: unexpected end of row
- decode bool: invalid value %d
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/b6f98d0032093e7a.
Report an issue: GitHub.