wavetermdev/waveterm · error

command cannot be empty

Error message

command cannot be empty

What it means

SendComplexRequest requires a non-empty command string because the command identifies which RPC route/method to invoke on the remote side. An empty command would create a request packet that cannot be dispatched, so it fails fast before registration.

Source

Thrown at pkg/wshutil/wshrpc.go:778

	return handler.done.Load()
}

func (w *WshRpc) SendComplexRequest(command string, data any, opts *wshrpc.RpcOpts) (rtnHandler *RpcRequestHandler, rtnErr error) {
	if w.IsServerDone() {
		return nil, errors.New("server is no longer running, cannot send new requests")
	}
	if opts == nil {
		opts = &wshrpc.RpcOpts{}
	}
	timeoutMs := opts.Timeout
	if timeoutMs <= 0 {
		timeoutMs = DefaultTimeoutMs
	}
	defer func() {
		panichandler.PanicHandler("SendComplexRequest", recover())
	}()
	if command == "" {
		return nil, fmt.Errorf("command cannot be empty")
	}
	handler := &RpcRequestHandler{
		w:           w,
		ctxCancelFn: &atomic.Pointer[context.CancelFunc]{},
	}
	var cancelFn context.CancelFunc
	handler.ctx, cancelFn = context.WithTimeout(context.Background(), time.Duration(timeoutMs)*time.Millisecond)
	handler.ctxCancelFn.Store(&cancelFn)
	if !opts.NoResponse {
		handler.reqId = uuid.New().String()
	}
	req := &RpcMessage{
		Command: command,
		ReqId:   handler.reqId,
		Data:    data,
		Timeout: timeoutMs,
		Route:   opts.Route,
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Pass the correct command constant (e.g. wshrpc.Command_* names) as the command argument.
  2. Validate the command string at the call site before invoking the request.
  3. Check where the command name originates (config/env/registry) — the source is returning empty.
  4. Autocomplete from the wshrpc command constants rather than typing string literals.

Example fix

// before
handler, err := w.SendComplexRequest(cmd, args, &wshutil.RpcOpts{Route: route})
// after
if cmd == "" { return nil, fmt.Errorf("no command configured") }
handler, err := w.SendComplexRequest(cmd, args, &wshutil.RpcOpts{Route: route})
Defensive patterns

Strategy: validation

Validate before calling

func validateCommand(cmd string) error {
    if strings.TrimSpace(cmd) == "" {
        return fmt.Errorf("rpc command must be a non-empty string")
    }
    return nil
}

Type guard

func hasCommand(cmd string) bool {
    return strings.TrimSpace(cmd) != ""
}

Try / catch

handler, err := w.SendComplexRequest(cmd, args, opts)
if err != nil && strings.Contains(err.Error(), "command cannot be empty") {
    return fmt.Errorf("misconfigured rpc command for %s: %w", route, err)
}

Prevention

When it happens

Trigger: Passing "" (or a variable that resolved to empty) as the command argument to SendComplexRequest/SendSimpleRequest; deriving the command name from config/env that is unset; typo leaving a constant blank.

Common situations: Command names built from user config or constants that were renamed/removed across versions; dynamic dispatch tables with missing entries; copy-paste leaving the command literal empty.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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