wavetermdev/waveterm · error
nil wshrpc passed to wshclient
Error message
nil wshrpc passed to wshclient
What it means
The generic wsh client helper sendRpcRequestCallHelper guards against a nil *wshutil.WshRpc: if the provided wshrpc is nil, calling methods on it would panic, so it returns this error instead. All single-response wsh commands (ActivityCommand, AuthenticateCommand, AiSendMessageCommand, etc.) funnel through this helper, so any of them can surface it.
Source
Thrown at pkg/wshrpc/wshclient/wshclientutil.go:22
package wshclient
import (
"context"
"errors"
"github.com/wavetermdev/waveterm/pkg/panichandler"
"github.com/wavetermdev/waveterm/pkg/util/utilfn"
"github.com/wavetermdev/waveterm/pkg/wshrpc"
"github.com/wavetermdev/waveterm/pkg/wshutil"
)
func sendRpcRequestCallHelper[T any](w *wshutil.WshRpc, command string, data interface{}, opts *wshrpc.RpcOpts) (T, error) {
if opts == nil {
opts = &wshrpc.RpcOpts{}
}
var respData T
if w == nil {
return respData, errors.New("nil wshrpc passed to wshclient")
}
if opts.NoResponse {
err := w.SendCommand(command, data, opts)
if err != nil {
return respData, err
}
return respData, nil
}
resp, err := w.SendRpcRequest(command, data, opts)
if err != nil {
return respData, err
}
err = utilfn.ReUnmarshal(&respData, resp)
if err != nil {
return respData, err
}
return respData, nil
}View on GitHub (pinned to a4447c1563)
Solutions
- Ensure the *wshutil.WshRpc is created and assigned (e.g. via the block controller/router setup) before invoking any wshclient commands.
- Add a nil check on the rpc reference at your call site and defer or abort the command if nil.
- If the rpc may come and go, hold it behind an accessor that returns (rpc, ok) and skip the command when not ready.
- In tests, inject a real or mock WshRpc rather than leaving the field zero-valued.
Example fix
// before
err := wshclient.AuthenticateCommand(rpc, authData, nil) // rpc may be nil
// after
if rpc == nil {
return fmt.Errorf("cannot authenticate: rpc client not initialized")
}
err := wshclient.AuthenticateCommand(rpc, authData, nil) Defensive patterns
Strategy: validation
Validate before calling
if rpc == nil {
return fmt.Errorf("wsh rpc client not initialized; cannot send command")
} Type guard
func rpcReady(w *wshutil.WshRpc) bool { return w != nil } Try / catch
resp, err := wshclient.AuthenticateCommand(rpc, data, nil)
if err != nil && strings.Contains(err.Error(), "nil wshrpc passed to wshclient") {
return fmt.Errorf("rpc client not initialized: %w", err)
}
if err != nil {
return err
} Prevention
- Initialize the WshRpc in the constructor of any controller that issues wsh commands.
- Never assign nil to an rpc field during teardown before stopping dependent commands.
- Centralize command dispatch in one helper that nil-checks the rpc once.
- In tests, always inject a real or mock WshRpc, never the zero value.
When it happens
Trigger: Passing a nil *wshutil.WshRpc to any generated wshclient command function, typically because the client/router was not yet initialized, initialization failed, or a struct field holding the rpc client was left unset (zero value).
Common situations: Calling wsh commands before the block/controller wiring finishes; shutdown races where the rpc object was cleared to nil; forgetting to assign the WshRpc field when constructing a controller manually; tests constructing commands without a mock rpc.
Related errors
- file info is required
- no route id available
- starting file stream: %w
- getting file info: %w
- removing file: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/64f19677f2661803.
Report an issue: GitHub.