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

  1. Verify the producer uses the same protocol version and respects MaxEventPayloadBytes
  2. Re-establish the bus connection to resynchronize the stream
  3. 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

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


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/7b08ca80a73afd8d. Report an issue: GitHub.