wavetermdev/waveterm · error

cancel packets must have reqid or resid set

Error message

cancel packets must have reqid or resid set

What it means

A cancel packet must identify which message it cancels via ReqId (cancel my request) or ResId (cancel the response/handler). With neither, the cancel is a no-op target-less packet, so Validate rejects it.

Source

Thrown at pkg/wshutil/wshrpc.go:154

	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")
		}
		return nil
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Populate ReqId with the original request's id when canceling an outgoing request
  2. Populate ResId when canceling an in-flight response on the responder side
  3. Only invoke cancel after the request id is known/assigned

Example fix

// before
msg := wshutil.RpcMessage{Cancel: true}
// after
msg := wshutil.RpcMessage{Cancel: true, ReqId: pendingReqId}
Defensive patterns

Strategy: validation

Validate before calling

if msg.Cancel && msg.ReqId == "" && msg.ResId == "" {
	return fmt.Errorf("cancel needs reqid or resid")
}
if err := msg.Validate(); err != nil { return err }

Type guard

func cancelHasTarget(msg wshutil.RpcMessage) bool {
	return msg.ReqId != "" || msg.ResId != ""
}

Try / catch

if err := msg.Validate(); err != nil {
	return fmt.Errorf("cancel packet missing target: %w", err)
}

Prevention

When it happens

Trigger: Calling Validate on an RpcMessage with Cancel=true, Command empty, and both ReqId and ResId empty.

Common situations: Cancelling a request before its ReqId was assigned (cancel called before SendRequest returned); a helper that constructs cancel messages from a zero-value message struct.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/d582e603c2dca84b. Report an issue: GitHub.