chenhg5/cc-connect · error

yuanbao: parse length at %d

Error message

yuanbao: parse length at %d

What it means

Thrown by parseFields when the length prefix of a length-delimited (wire type 2) field cannot be decoded as a varint at the current offset. decodeVarint returned n==0, meaning the buffer ends inside the length varint itself — the data ends before the field's length could even be read.

Source

Thrown at platform/yuanbao/proto.go:156

		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) {
				return nil, fmt.Errorf("yuanbao: 64-bit truncated at %d", pos)
			}
			fields = append(fields, field{fieldNum, wt, binary.LittleEndian.Uint64(data[pos : pos+8])})
			pos += 8
		case wt32Bit:
			if pos+4 > len(data) {
				return nil, fmt.Errorf("yuanbao: 32-bit truncated at %d", pos)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Ensure the complete frame is buffered before calling the decoder (check length header vs. bytes read).
  2. Log the offset and byte dump to confirm where truncation occurs and fix the framing/reassembly code.
  3. Reconnect and re-fetch the message; a truncated payload cannot be repaired locally.
  4. Check for server protocol changes that may have introduced new/changed field encoding.

Example fix

// before
payload := buf[:n] // n = bytes read this tick
cm, err := decodeConnMsg(payload)
// after
if n < expectedFrameLen {
    return nil // wait for the rest of the frame
}
cm, err := decodeConnMsg(buf[:n])
Defensive patterns

Strategy: validation

Validate before calling

if len(buf) < expectedFrameLen {
    return nil // wait for remaining bytes before decoding
}

Try / catch

cm, err := decodeConnMsg(raw)
if err != nil {
    slog.Warn("yuanbao: incomplete frame", "err", err)
    return // frame will be re-requested after reconnect
}

Prevention

When it happens

Trigger: A length-delimited field's tag was parsed but the length varint is incomplete: message truncated immediately after the tag, or a 10+ byte malformed length. Reached via any of the yuanbao decode entry points (decodeConnMsg, decodeAuthBindRsp, decodeInboundPush, decodeMsgBodyElement).

Common situations: Partial WebSocket frame delivery, incorrect frame reassembly, or feeding a sub-slice that cuts the message before its length-delimited fields.

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/ceb7c32769d54808. Report an issue: GitHub.