wavetermdev/waveterm · error
cancel packets may not have command set
Error message
cancel packets may not have command set
What it means
Packet validation error: CANCEL packets must not carry a command. Cancelling identifies the target solely by resid; setting command on a cancel packet violates the wire protocol and the packet is rejected.
Source
Thrown at pkg/wshutil/wshrpc.go:151
Source string `json:"source,omitempty"` // source route id
Cont bool `json:"cont,omitempty"` // flag if additional requests/responses are forthcoming
Cancel bool `json:"cancel,omitempty"` // used to cancel a streaming request or response (sent from the side that is not streaming)
Error string `json:"error,omitempty"`
DataType string `json:"datatype,omitempty"`
Data any `json:"data,omitempty"`
}
func (r *RpcMessage) IsRpcRequest() bool {
return r.Command != "" || r.ReqId != ""
}
func (r *RpcMessage) Validate() error {
if r.ReqId != "" && r.ResId != "" {
return fmt.Errorf("request packets may not have both reqid and resid set")
}
if r.Cancel {
if r.Command != "" {
return fmt.Errorf("cancel packets may not have command set")
}
if r.ReqId == "" && r.ResId == "" {
return fmt.Errorf("cancel packets must have reqid or resid set")
}
if r.Data != nil {
return fmt.Errorf("cancel packets may not have data set")
}
return nil
}
if r.Command != "" {
if r.ResId != "" {
return fmt.Errorf("command packets may not have resid set")
}
if r.Error != "" {
return fmt.Errorf("command packets may not have error set")
}
if r.DataType != "" {
return fmt.Errorf("command packets may not have datatype set")View on GitHub (pinned to a4447c1563)
Solutions
- Remove the Command field when canceling (send only Cancel + the target ReqId/ResId)
- Construct the cancel message fresh: RpcMessage{Cancel: true, ReqId: originalReqId}
- Check code paths that set Cancel=true so they do not leave Command populated
Example fix
// before
msg := wshutil.RpcMessage{Cancel: true, Command: "controller.sendinput", ReqId: origId}
// after
msg := wshutil.RpcMessage{Cancel: true, ReqId: origId} Defensive patterns
Strategy: validation
Validate before calling
if msg.Cancel && msg.Command != "" {
msg.Command = ""
}
if err := msg.Validate(); err != nil { return err } Type guard
func isWellFormedCancel(msg wshutil.RpcMessage) bool {
return !msg.Cancel || (msg.Command == "" && (msg.ReqId != "" || msg.ResId != "") && msg.Data == nil)
} Try / catch
if err := msg.Validate(); err != nil {
return fmt.Errorf("invalid cancel packet: %w", err)
} Prevention
- Use a dedicated CancelRequest(reqId) helper
- Do not toggle Cancel on an existing command message
- Keep control packets minimal — only Cancel + id fields
When it happens
Trigger: Calling Validate on an RpcMessage with Cancel=true and Command set to a non-empty string.
Common situations: A caller builds a normal command message then flips Cancel=true to cancel it instead of clearing the command; generic message-mutation helpers that toggle Cancel without scrubbing other fields.
Related errors
- cancel packets must have reqid or resid set
- cancel packets may not have data set
- blockid is required
- size must be greater than 0
- invalid context, must have a routeid
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/12f8978abddf3ec1.
Report an issue: GitHub.