chenhg5/cc-connect · error

yuanbao: parse head: %w

Error message

yuanbao: parse head: %w

What it means

Thrown by decodeConnMsg when parsing the nested connHead sub-message (field 1) fails; the underlying parseFields error is wrapped with %w. The outer message parsed, but its header bytes are malformed protobuf, so the command/sequence metadata cannot be extracted.

Source

Thrown at platform/yuanbao/proto.go:276

	seqNo int
	data  []byte
}

func decodeConnMsg(raw []byte) (*connMsg, error) {
	if len(raw) == 0 {
		return nil, fmt.Errorf("yuanbao: empty conn msg")
	}
	fields, err := parseFields(raw)
	if err != nil {
		return nil, err
	}
	headBytes := getBytes(fields, 1)
	payload := getBytes(fields, 2)
	var head connHead
	if len(headBytes) > 0 {
		hf, err := parseFields(headBytes)
		if err != nil {
			return nil, fmt.Errorf("yuanbao: parse head: %w", err)
		}
		head = connHead{
			cmdType: int(getVarint(hf, 1)),
			cmd:     getString(hf, 2),
			seqNo:   int(getVarint(hf, 3)),
			msgID:   getString(hf, 4),
			module:  getString(hf, 5),
			needAck: getVarint(hf, 6) != 0,
			status:  int(getVarint(hf, 10)),
		}
	}
	return &connMsg{head: head, seqNo: head.seqNo, data: payload}, nil
}

type authBindRsp struct {
	code      int
	message   string
	connectID string

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Log the wrapped inner error plus a hex dump of headBytes to identify which head field breaks parsing.
  2. Verify getBytes(fields, 1) returns the correct field — dump all outer fields to check the outer parse didn't desync.
  3. Capture a frame from the server and decode with protoc --decode_raw to compare against the adapter's connHead layout.
  4. Update the adapter's head structure if the server protocol changed.
  5. If corruption in transit is suspected, reconnect and re-authenticate.

Example fix

// before
hf, err := parseFields(headBytes)
if err != nil {
    return nil, fmt.Errorf("yuanbao: parse head: %w", err)
}
// after (caller: diagnose + tolerate)
cm, err := decodeConnMsg(raw)
if err != nil && strings.Contains(err.Error(), "parse head") {
    slog.Warn("yuanbao: malformed head", "head", hex.Dump(headBytes), "err", err)
    return nil // drop frame; keep connection alive
}
Defensive patterns

Strategy: try-catch

Validate before calling

func headPresent(fields []field) bool {
    h := getBytes(fields, 1)
    return len(h) > 0
}

Try / catch

cm, err := decodeConnMsg(raw)
if err != nil {
    if strings.Contains(err.Error(), "parse head") {
        slog.Warn("yuanbao: malformed head, dropping frame", "err", err,
            "inner", errors.Unwrap(err))
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: The bytes returned by getBytes(fields, 1) are not valid protobuf — server changed the head encoding, the head field got corrupted in transit, or the outer parse desynchronized and grabbed wrong bytes as the head. Callers: authenticate, handleFrame.

Common situations: Yuanbao server protocol update altering connHead fields; a proxy corrupting small header payloads; a bug where a varint field value is passed instead of its bytes to the head parser.

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