chenhg5/cc-connect · error
yuanbao: empty conn msg
Error message
yuanbao: empty conn msg
What it means
Thrown by decodeConnMsg when handed a zero-length raw buffer: there are no fields to parse at all, so no connMsg can be produced. It's a fast-fail guard before parseFields is invoked, distinguishing 'empty payload' from 'malformed payload'.
Source
Thrown at platform/yuanbao/proto.go:264
type connHead struct {
cmdType int
cmd string
seqNo int
msgID string
module string
needAck bool
status int
}
type connMsg struct {
head connHead
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),View on GitHub (pinned to 4000b2338a)
Solutions
- Check len(raw) before calling decodeConnMsg and skip/dispatch empty frames to the appropriate handler (ping/ack).
- Treat an empty payload in a message-expecting frame as a protocol error and log it with the frame command type from the header.
- If the empty buffer comes from getBytes(fields, N) returning nil for an absent field, check field presence before decoding the sub-message.
- Verify the server isn't sending empty bodies due to an API change; capture a frame dump to confirm.
Example fix
// before
raw := frame.Payload
cm, err := decodeConnMsg(raw)
// after
if len(frame.Payload) == 0 {
switch frame.Cmd { // dispatch empties to heartbeat handling
case cmdPing:
handlePing(); return
default:
slog.Warn("yuanbao: empty conn msg body", "cmd", frame.Cmd)
return
}
}
cm, err := decodeConnMsg(frame.Payload) Defensive patterns
Strategy: validation
Validate before calling
func shouldDecodeConnMsg(frame Frame) bool {
return len(frame.Payload) > 0
} Try / catch
cm, err := decodeConnMsg(raw)
if err != nil {
if strings.Contains(err.Error(), "empty conn msg") {
return nil // benign: heartbeat/empty frame
}
return err
} Prevention
- Dispatch empty frames (ping/ack) before the connMsg decode path.
- Check field presence before re-decoding sub-messages from getBytes results.
- Log the frame command alongside empty-payload warnings.
- Add a test asserting heartbeats never reach decodeConnMsg.
When it happens
Trigger: The transport delivered a frame whose body is empty (heartbeat/keepalive variant not handled upstream), or a caller slices a zero-length region (e.g. getBytes returned nil for a missing field 2 and that nil is re-decoded). Reached from authenticate, handleFrame, and tests.
Common situations: Handling a ping/pong or ack frame with no payload through the connMsg path; server sending an empty DATA frame; a sub-message field absent so getBytes returns nil which is then decoded.
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
- yuanbao: empty data
- yuanbao: parse varint tag failed at %d
- yuanbao: parse varint at %d
- yuanbao: parse length at %d
- yuanbao: length %d exceeds data at %d
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/acb8ab88dfb7ffb6.
Report an issue: GitHub.