yudai/gotty · error
received malformed remote command for terminal resize: empty
Error message
received malformed remote command for terminal resize: empty payload
What it means
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.
Source
Thrown at webtty/webtty.go:190
_, err := wt.slave.Write(data[1:])
if err != nil {
return errors.Wrapf(err, "failed to write received data to slave")
}
case Ping:
err := wt.masterWrite([]byte{Pong})
if err != nil {
return errors.Wrapf(err, "failed to return Pong message to master")
}
case ResizeTerminal:
if wt.columns != 0 && wt.rows != 0 {
break
}
if len(data) <= 1 {
return errors.New("received malformed remote command for terminal resize: empty payload")
}
var args argResizeTerminal
err := json.Unmarshal(data[1:], &args)
if err != nil {
return errors.Wrapf(err, "received malformed data for terminal resize")
}
rows := wt.rows
if rows == 0 {
rows = int(args.Rows)
}
columns := wt.columns
if columns == 0 {
columns = int(args.Columns)
}
wt.slave.ResizeTerminal(columns, rows)View on GitHub (pinned to a080c85cbc)
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
Example fix
// before
conn.WriteMessage(ws.TextMessage, []byte{ResizeTerminal})
// after
payload, _ := json.Marshal(argResizeTerminal{Columns: 80, Rows: 24})
msg := append([]byte{ResizeTerminal}, payload...)
conn.WriteMessage(ws.TextMessage, msg) Defensive patterns
Strategy: validation
Validate before calling
func validResizeFrame(msg []byte) bool {
return len(msg) > 1 && json.Valid(msg[1:])
} Type guard
func isResizeFrame(msg []byte, resize byte) bool {
return len(msg) > 0 && msg[0] == resize && len(msg) > 1
} Try / catch
if err := conn.WriteControl/writeMsg(frame); err != nil || !validResizeFrame(frame) {
// fix encoder before sending
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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}.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
AI-assisted analysis of yudai/gotty@a080c85cbc (2026-09-02).
Data as JSON: /api/errors/3d8c3a7b814bb93b.
Report an issue: GitHub.