{"record":{"id":"a69e0db99bb22b02","repo":"larksuite/cli","slug":"protocol-encode-w","errorCode":null,"errorMessage":"protocol encode: %w","messagePattern":"protocol encode: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/event/adapter/localbus/protocol/codec.go","lineNumber":48,"sourceCode":"\n// MaxFrameBytes bounds reader buffer growth. It must stay above\n// MaxEventPayloadBytes, or the bus can frame an event the consumer then refuses\n// to read.\nconst MaxFrameBytes = MaxEventPayloadBytes + maxFrameOverheadBytes\n\n// ErrFrameTooLarge is returned by ReadFrame when a single frame exceeds MaxFrameBytes.\nvar ErrFrameTooLarge = errors.New(\"protocol: frame exceeds MaxFrameBytes\")\n\nconst WriteTimeout = 5 * time.Second // bound writes against wedged peer kernel buffer\n\ntype typeEnvelope struct {\n\tType string `json:\"type\"`\n}\n\nfunc Encode(w io.Writer, msg interface{}) error {\n\tdata, err := json.Marshal(msg)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"protocol encode: %w\", err)\n\t}\n\tdata = append(data, '\\n')\n\t_, err = w.Write(data)\n\treturn err\n}\n\nfunc EncodeWithDeadline(conn net.Conn, msg interface{}, timeout time.Duration) error {\n\tif err := conn.SetWriteDeadline(time.Now().Add(timeout)); err != nil {\n\t\treturn err\n\t}\n\treturn Encode(conn, msg)\n}\n\n// ReadFrame reads one newline-delimited message; caps at MaxFrameBytes to defang slowloris.\nfunc ReadFrame(br *bufio.Reader) ([]byte, error) {\n\tvar buf []byte\n\tfor {\n\t\tchunk, err := br.ReadSlice('\\n')","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/event/adapter/localbus/protocol/codec.go#L30-L66","documentation":"protocol.Encode wraps json.Marshal failures when serializing a message to the newline-delimited JSON wire protocol. Marshal only fails for unsupported types (channels, funcs, cyclic structures), so in practice this indicates a programmer error in the message struct, not bad wire data. The write error itself is returned unwrapped from w.Write.","triggerScenarios":"Calling Encode (directly or via handle's message flow) with a msg value that json.Marshal cannot serialize: an unmarshalable field type (chan, func, complex), a cyclic pointer graph, or an invalid utf-8/systr trick that makes Marshal error.","commonSituations":"Someone added a field of unsupported type to Hello/Event/StatusResponse structs; passing a raw map containing function values; embedding a context or sync.Mutex-like value that trips marshaling rules.","solutions":["Inspect the %w cause: it names the unsupported type or cycle","Fix the message struct: remove or replace chan/func/complex fields with serializable types or json:\"-\" tags","Break cyclic references before encoding (store IDs instead of back-pointers)","Test with a unit encode of the concrete message type (see TestEncodeDecode*) before shipping"],"exampleFix":"// before\ntype Event struct {\n    Ack func() `json:\"ack\"`\n}\n// after\ntype Event struct {\n    Ack func() `json:\"-\"`\n}","handlingStrategy":"try-catch","validationCode":"if err := json.Marshal(msg); err != nil {\n\treturn fmt.Errorf(\"message not encodable: %w\", err)\n}\n// run before handing msg to protocol.Encode","typeGuard":"func encodable(msg any) bool {\n\treturn json.Marshal(msg) == nil\n}","tryCatchPattern":"if err := protocol.Encode(w, msg); err != nil {\n\tvar ue *json.UnsupportedTypeError\n\tvar ce *json.UnsupportedValueError\n\tswitch {\n\tcase errors.As(err, &ue):\n\t\tlog.Printf(\"unsupported field type %s in %T\", ue.Type, msg)\n\tcase errors.As(err, &ce):\n\t\tlog.Printf(\"unsupported value in %T: %v\", msg, ce.Value)\n\tdefault:\n\t\t// write failure on w: check pipe/socket state\n\t}\n}","preventionTips":["Keep protocol message structs limited to JSON-serializable types (no chan/func fields without json:\"-\")","Add round-trip tests (Encode+Decode) for every new message type","Avoid cyclic pointers between Event and parent structures","Validate messages in CI with a fuzz or example-based encode test"],"tags":["go","json","serialization","localbus-protocol"],"backgroundTag":"json-marshal-failed","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}