chenhg5/cc-connect · error

yuanbao: 32-bit truncated at %d

Error message

yuanbao: 32-bit truncated at %d

What it means

Thrown by parseFields when a 32-bit fixed-width field (wire type 5, wt32Bit) is present but fewer than 4 bytes remain in the buffer (pos+4 > len(data)). The decoder refuses to read a partial fixed32 value, indicating message truncation or cursor desynchronization.

Source

Thrown at platform/yuanbao/proto.go:174

				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)
			}
			fields = append(fields, field{fieldNum, wt, uint64(binary.LittleEndian.Uint32(data[pos : pos+4]))})
			pos += 4
		default:
			return nil, fmt.Errorf("yuanbao: unknown wire type %d at %d", wt, pos)
		}
	}
	return fields, nil
}

func decodeVarint(data []byte) (uint64, int) {
	var result uint64
	var shift uint
	for i, b := range data {
		result |= uint64(b&0x7F) << shift
		shift += 7
		if b&0x80 == 0 {
			return result, i + 1

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Confirm the byte count read from the transport matches the frame's declared length before decoding.
  2. Hex-dump the tail of the failing buffer to see whether real data was cut or garbage was appended; fix the framing code accordingly.
  3. Resync the connection (reconnect) after a malformed frame instead of continuing to parse the stream.
  4. Audit parseFields for any code path that advances pos by the wrong amount, which desyncs later fixed32 fields.

Example fix

// before
msg := make([]byte, declared)
copy(msg, buf)
cm, err := decodeConnMsg(msg)
// after
if len(buf) < declared {
    return nil // incomplete frame; wait for remaining bytes
}
cm, err := decodeConnMsg(buf[:declared])
Defensive patterns

Strategy: try-catch

Type guard

func hasFixed32(b []byte, pos int) bool { return pos+4 <= len(b) }

Try / catch

cm, err := decodeConnMsg(raw)
if err != nil {
    slog.Warn("yuanbao: truncated fixed32, dropping frame", "err", err)
    return
}

Prevention

When it happens

Trigger: A frame ending in a fixed32 field (e.g. a float or checksum) arrives short by 1–3 bytes; or trailing garbage after a truncated frame is misread as a wt32Bit tag. Reached via decodeConnMsg, decodeAuthBindRsp, decodeInboundPush, decodeMsgBodyElement.

Common situations: Frame reassembly bug dropping trailing bytes, proxy truncating long messages, or the parser consuming wrong byte counts earlier in the message (e.g. a wire type unsupported earlier caused misalignment).

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