{"record":{"id":"3d8c3a7b814bb93b","repo":"yudai/gotty","slug":"received-malformed-remote-command-for-terminal-res","errorCode":null,"errorMessage":"received malformed remote command for terminal resize: empty payload","messagePattern":"received malformed remote command for terminal resize: empty payload","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"webtty/webtty.go","lineNumber":190,"sourceCode":"\n\t\t_, err := wt.slave.Write(data[1:])\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"failed to write received data to slave\")\n\t\t}\n\n\tcase Ping:\n\t\terr := wt.masterWrite([]byte{Pong})\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"failed to return Pong message to master\")\n\t\t}\n\n\tcase ResizeTerminal:\n\t\tif wt.columns != 0 && wt.rows != 0 {\n\t\t\tbreak\n\t\t}\n\n\t\tif len(data) <= 1 {\n\t\t\treturn errors.New(\"received malformed remote command for terminal resize: empty payload\")\n\t\t}\n\n\t\tvar args argResizeTerminal\n\t\terr := json.Unmarshal(data[1:], &args)\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"received malformed data for terminal resize\")\n\t\t}\n\t\trows := wt.rows\n\t\tif rows == 0 {\n\t\t\trows = int(args.Rows)\n\t\t}\n\n\t\tcolumns := wt.columns\n\t\tif columns == 0 {\n\t\t\tcolumns = int(args.Columns)\n\t\t}\n\n\t\twt.slave.ResizeTerminal(columns, rows)","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/yudai/gotty/blob/a080c85cbc59226c94c6941ad8c395232d72d517/webtty/webtty.go#L172-L208","documentation":"When a ResizeTerminal message arrives before columns/rows are known, WebTTY requires a JSON payload after the 1-byte message-type prefix. If len(data) <= 1 there is no payload to unmarshal, so this descriptive error is returned instead of a confusing json error.","triggerScenarios":"Client sends a single-byte message with the ResizeTerminal type identifier and no JSON arguments following it, while wt.columns==0 && wt.rows==0 (initial dims unset).","commonSituations":"Custom websocket clients that send only the command byte; truncated frames from a buggy proxy; hand-written clients that forget the JSON body {columns, rows}.","solutions":["Send the full frame: type byte followed by JSON like {\"columns\":80,\"rows\":24}","Fix the client encoder so the payload is appended after the message-type byte","Check intermediate proxies/websocket bridges for frame truncation"],"exampleFix":"// before\nconn.WriteMessage(ws.TextMessage, []byte{ResizeTerminal})\n// after\npayload, _ := json.Marshal(argResizeTerminal{Columns: 80, Rows: 24})\nmsg := append([]byte{ResizeTerminal}, payload...)\nconn.WriteMessage(ws.TextMessage, msg)","handlingStrategy":"validation","validationCode":"func validResizeFrame(msg []byte) bool {\n    return len(msg) > 1 && json.Valid(msg[1:])\n}","typeGuard":"func isResizeFrame(msg []byte, resize byte) bool {\n    return len(msg) > 0 && msg[0] == resize && len(msg) > 1\n}","tryCatchPattern":"if err := conn.WriteControl/writeMsg(frame); err != nil || !validResizeFrame(frame) {\n    // fix encoder before sending\n}","preventionTips":["Always append JSON args after the 1-byte command type","Unit-test client frames against the WebTTY protocol before shipping","Beware proxies that may truncate small frames"],"tags":["websocket","protocol","terminal-resize"],"backgroundTag":"malformed-websocket-message","analyzedSha":"a080c85cbc59226c94c6941ad8c395232d72d517","analyzedAt":"2026-09-02T16:42:38.150Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}