wavetermdev/waveterm · error
invalid packet: must have command, reqid, or resid set
Error message
invalid packet: must have command, reqid, or resid set
What it means
Every RpcMessage must be classifiable as a request (Command set), a response (ResId set), or otherwise carry ReqId. Validate() returns this error when Command, ReqId, and ResId are all empty — the packet has no routing identity and cannot be dispatched.
Source
Thrown at pkg/wshutil/wshrpc.go:194
}
if r.Timeout != 0 {
return fmt.Errorf("non-command request packets may not have timeout set")
}
return nil
}
if r.ResId != "" {
if r.Command != "" {
return fmt.Errorf("response packets may not have command set")
}
if r.ReqId == "" {
return fmt.Errorf("response packets must have reqid set")
}
if r.Timeout != 0 {
return fmt.Errorf("response packets may not have timeout set")
}
return nil
}
return fmt.Errorf("invalid packet: must have command, reqid, or resid set")
}
type rpcData struct {
Command string
Route string
ResCh chan *RpcMessage
Handler *RpcRequestHandler
}
func validateServerImpl(serverImpl ServerImpl) {
if serverImpl == nil {
return
}
serverType := reflect.TypeOf(serverImpl)
if serverType.Kind() != reflect.Pointer && serverType.Elem().Kind() != reflect.Struct {
panic(fmt.Sprintf("serverImpl must be a pointer to struct, got %v", serverType))
}
}View on GitHub (pinned to a4447c1563)
Solutions
- Populate Command (plus ReqId) for requests or ResId/ReqId for responses before sending.
- Check that the message actually got serialized/deserialized with the expected fields (field-name/tag mismatches).
- Guard send paths with Validate() and skip/log packets that fail rather than pushing them onto OutputCh.
- Upgrade both ends of the connection to matching wshutil versions to avoid field-shape drift.
Example fix
// before
w.OutputCh <- &wshutil.WshRpcDataStream{MsgBytes: mustJSON(wshrpc.RpcMessage{})}
// after
w.OutputCh <- &wshutil.WshRpcDataStream{MsgBytes: mustJSON(wshrpc.RpcMessage{Command: "waveclient:get", ReqId: genId()})} Defensive patterns
Strategy: validation
Validate before calling
func checkPacketIdentity(m wshrpc.RpcMessage) error {
if m.Command == "" && m.ReqId == "" && m.ResId == "" {
return fmt.Errorf("packet has no command/reqid/resid")
}
return nil
} Type guard
func hasIdentity(m wshrpc.RpcMessage) bool {
return m.Command != "" || m.ReqId != "" || m.ResId != ""
} Prevention
- Never send zero-value RpcMessage structs.
- Call Validate() on packets before enqueueing them.
- Keep both wshutil endpoints on the same version to avoid serialization field drift.
- Log raw marshaled packets when debugging dispatch failures.
When it happens
Trigger: Sending a zero-value RpcMessage, an empty payload, or a message whose meaningful fields live only in nested data without any of the three required fields set.
Common situations: Uninitialized structs passed to the writer; JSON round-trips that dropped fields due to schema mismatch between versions; generic forwarding code that passes through empty envelopes.
Related errors
- response packets may not have command set
- response packets must have reqid set
- response packets may not have timeout set
- call ${methodName} error: ${respData.error}
- rpc command "${msg.command}" not supported by [${this.routeI
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/8bc1bdad4e1631f5.
Report an issue: GitHub.