larksuite/cli · error
protocol decode type: %w
Error message
protocol decode type: %w
What it means
protocol.Decode first unmarshals the line into a typeEnvelope just to read the 'type' discriminator. If the line is not valid JSON at all, it cannot even determine the type and returns this wrapped error. It is the first of two decode steps (the per-type unmarshal failure is wrapped separately as 'protocol decode %s').
Source
Thrown at internal/event/adapter/localbus/protocol/codec.go:90
if len(buf)+len(chunk) > MaxFrameBytes {
return nil, ErrFrameTooLarge
}
return append(buf, chunk...), nil
case bufio.ErrBufferFull:
if len(buf)+len(chunk) > MaxFrameBytes {
return nil, ErrFrameTooLarge
}
buf = append(buf, chunk...)
default:
return nil, err
}
}
}
func Decode(line []byte) (interface{}, error) {
var env typeEnvelope
if err := json.Unmarshal(line, &env); err != nil {
return nil, fmt.Errorf("protocol decode type: %w", err)
}
var msg interface{}
switch env.Type {
case MsgTypeHello:
msg = &Hello{}
case MsgTypeHelloAck:
msg = &HelloAck{}
case MsgTypeEvent:
msg = &Event{}
case MsgTypeBye:
msg = &Bye{}
case MsgTypePreShutdownCheck:
msg = &PreShutdownCheck{}
case MsgTypePreShutdownAck:
msg = &PreShutdownAck{}
case MsgTypeStatusQuery:
msg = &StatusQuery{}View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Check the %w cause for the exact JSON syntax error offset and inspect the offending line content
- Ensure the peer writes newline-delimited JSON only (use protocol.Encode) — no logging or binary writes to the shared pipe/socket
- Verify both sides use the same protocol version/binary; restart the bus process to clear a corrupted stream
- Make the reader tolerant: skip/discard empty or undecodable lines instead of treating the whole stream as fatal, if resync is acceptable
Example fix
// before: writing raw text into the pipe
fmt.Fprintf(conn, "hello %s\n", name)
// after
protocol.Encode(conn, &protocol.Hello{Name: name}) Defensive patterns
Strategy: try-catch
Validate before calling
func validFrame(line []byte) bool {
line = bytes.TrimSpace(line)
if len(line) == 0 || !json.Valid(line) {
return false
}
return true
} Type guard
func isDecodeTypeError(err error) bool {
return err != nil && strings.HasPrefix(err.Error(), "protocol decode type:")
} Try / catch
msg, err := protocol.Decode(line)
if err != nil {
log.Printf("dropping bad frame %q: %v", line, err)
continue // resync on next newline-delimited frame instead of aborting the stream
} Prevention
- Only write to the bus stream via protocol.Encode; route logs elsewhere
- Ensure frames are newline-terminated before reading the next line
- Check for truncated writes: flush/close writers and handle partial-write errors
- Verify both endpoints link the same protocol package version
When it happens
Trigger: Decode receives a line that is not parseable JSON: empty line, partial write/truncated frame, plain-text garbage on the socket/pipe, or a frame split incorrectly by the newline framing (e.g. binary data injected into the stream).
Common situations: Writer process crashed mid-frame leaving a partial line; a log line got mixed into the bus pipe; client speaks a different/older protocol version writing non-JSON; reading a file that contains multiple concatenated non-newline-delimited blobs.
Related errors
- protocol encode: %w
- ErrMalformedConfig
- protocol: unknown message type %q
- invalid v0.2 index: %w
- fetch bot info: unmarshal: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/735947f9ef09ff06.
Report an issue: GitHub.