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

  1. Ensure the *wshutil.WshRpc is created and assigned (e.g. via the block controller/router setup) before invoking any wshclient commands.
  2. Add a nil check on the rpc reference at your call site and defer or abort the command if nil.
  3. If the rpc may come and go, hold it behind an accessor that returns (rpc, ok) and skip the command when not ready.
  4. 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

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


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