chenhg5/cc-connect · error

yuanbao: parse varint at %d

Error message

yuanbao: parse varint at %d

What it means

Thrown by parseFields when the value varint for a field with wire type wtVarint cannot be decoded at the current offset. Like the tag error, decodeVarint returned n==0 because the buffer ends mid-varint or the varint is malformed (overlong, >10 bytes). The tag was parsed successfully but the payload is truncated right after it.

Source

Thrown at platform/yuanbao/proto.go:149

func parseFields(data []byte) ([]field, error) {
	if len(data) == 0 {
		return nil, fmt.Errorf("yuanbao: empty data")
	}
	var fields []field
	pos := 0
	for pos < len(data) {
		tag, n := decodeVarint(data[pos:])
		if n == 0 {
			return nil, fmt.Errorf("yuanbao: parse varint tag failed at %d", pos)
		}
		pos += n
		fieldNum := int(tag >> 3)
		wt := int(tag & 0x07)
		switch wt {
		case wtVarint:
			val, n := decodeVarint(data[pos:])
			if n == 0 {
				return nil, fmt.Errorf("yuanbao: parse varint at %d", pos)
			}
			fields = append(fields, field{fieldNum, wt, val})
			pos += n
		case wtLen:
			ln, n := decodeVarint(data[pos:])
			if n == 0 {
				return nil, fmt.Errorf("yuanbao: parse length at %d", pos)
			}
			pos += n
			if pos+int(ln) > len(data) {
				return nil, fmt.Errorf("yuanbao: length %d exceeds data at %d", ln, pos)
			}
			val := make([]byte, ln)
			copy(val, data[pos:pos+int(ln)])
			fields = append(fields, field{fieldNum, wt, val})
			pos += int(ln)
		case wt64Bit:
			if pos+8 > len(data) {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check that the full frame body was read before decoding (compare bytes read vs. frame length header).
  2. Log offset pos and the remaining bytes to confirm truncation, then fix the upstream read loop to buffer until the frame is complete.
  3. Re-request the message from the server (reconnect) since truncated data is unrecoverable.
  4. Verify the yuanbao server protocol version hasn't changed the field encoding.

Example fix

// before
val, n := decodeVarint(data[pos:])
if n == 0 {
    return nil, fmt.Errorf("yuanbao: parse varint at %d", pos)
}
// after (caller side: ensure complete frame)
if len(buf) < frameLen {
    return nil, io.ErrUnexpectedEOF // wait for more bytes instead of parsing
}
val, n := decodeVarint(data[pos:])
if n == 0 {
    return nil, fmt.Errorf("yuanbao: parse varint at %d", pos)
}
Defensive patterns

Strategy: validation

Validate before calling

if len(frame.Payload) < frame.DeclaredLen {
    return errors.New("frame incomplete, do not decode")
}

Try / catch

fields, err := parseFields(data)
if err != nil {
    slog.Warn("malformed varint payload", "offset", pos, "err", err)
    conn.Reconnect()
    return
}

Prevention

When it happens

Trigger: A protobuf message whose last field is a varint but whose bytes are cut off after the tag — e.g. a truncated frame from the WebSocket, or a length-prefixed sub-message whose declared length exceeds the available bytes. Hit on any decodeConnMsg/decodeAuthBindRsp/decodeInboundPush/decodeMsgBodyElement path.

Common situations: Network layer delivered a partial frame, a bug in the caller's slice bounds chopped the message tail, or server-side serialization changed producing incompatible payloads.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/4a17c0261ba4c6a5. Report an issue: GitHub.