larksuite/cli · error
protocol: frame exceeds MaxFrameBytes
Error message
protocol: frame exceeds MaxFrameBytes
What it means
ErrFrameTooLarge is returned by ReadFrame when a single frame read from the local bus exceeds MaxFrameBytes (= MaxEventPayloadBytes + overhead). The bound exists so reader buffer growth is capped; the constant deliberately stays above MaxEventPayloadBytes so the bus never frames an event a consumer would then refuse to read. Hitting it means the stream delivered a frame larger than the protocol allows, indicating a corrupted or misbehaving peer.
Source
Thrown at internal/event/adapter/localbus/protocol/codec.go:37
// keeps the two in step, since the ingress deliberately does not import this
// package.
const MaxEventPayloadBytes = 1 << 20
// maxFrameOverheadBytes is the room a frame gets on top of its payload for the
// canonical metadata and JSON punctuation around it. Worst-case realistic
// metadata measures a few hundred bytes, so this is generous on purpose: a
// frame limit that merely equalled the payload limit would make the top of the
// accepted payload range undeliverable, which is how an accepted event turned
// into a dropped one.
const maxFrameOverheadBytes = 4 << 10
// MaxFrameBytes bounds reader buffer growth. It must stay above
// MaxEventPayloadBytes, or the bus can frame an event the consumer then refuses
// to read.
const MaxFrameBytes = MaxEventPayloadBytes + maxFrameOverheadBytes
// ErrFrameTooLarge is returned by ReadFrame when a single frame exceeds MaxFrameBytes.
var ErrFrameTooLarge = errors.New("protocol: frame exceeds MaxFrameBytes")
const WriteTimeout = 5 * time.Second // bound writes against wedged peer kernel buffer
type typeEnvelope struct {
Type string `json:"type"`
}
func Encode(w io.Writer, msg interface{}) error {
data, err := json.Marshal(msg)
if err != nil {
return fmt.Errorf("protocol encode: %w", err)
}
data = append(data, '\n')
_, err = w.Write(data)
return err
}
func EncodeWithDeadline(conn net.Conn, msg interface{}, timeout time.Duration) error {View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Verify the producer uses the same protocol version and respects MaxEventPayloadBytes
- Re-establish the bus connection to resynchronize the stream
- Audit for foreign/corrupt writers on the bus transport
Defensive patterns
Strategy: validation
Validate before calling
if len(payload) > protocol.MaxEventPayloadBytes {
return fmt.Errorf("event payload %d exceeds limit %d", len(payload), protocol.MaxEventPayloadBytes)
} Type guard
func isFrameTooLarge(err error) bool { return errors.Is(err, protocol.ErrFrameTooLarge) } Try / catch
frame, err := protocol.ReadFrame(r)
if errors.Is(err, protocol.ErrFrameTooLarge) {
// drop connection and resync; peer violated the protocol
} Prevention
- Keep event payloads within MaxEventPayloadBytes
- Use matching protocol versions on producer and consumer
- Restrict write access to the bus transport to trusted processes
- Log and reconnect on any ErrFrameTooLarge instead of continuing a desynced stream
When it happens
Trigger: Reading from a localbus connection where the peer writes a frame larger than MaxFrameBytes (codec.go:73 and :78 both return it when len(buf)+len(chunk) exceeds the cap, including on bufio.ErrBufferFull).
Common situations: A producer built against a different/larger payload limit; a corrupted or desynchronized stream misinterpreting payload bytes as a huge length; a foreign process writing to the same socket/pipe.
Related errors
- protocol decode %s: %w
- app registration failed: response missing device_code
- app registration returned credentials with a contradictory t
- busdiscover: mkdir %s: %w
- busdiscover: write pid tmp: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/7b08ca80a73afd8d.
Report an issue: GitHub.