wavetermdev/waveterm · error
command %q invalid multi arg payload
Error message
command %q invalid multi arg payload
What it means
For commands declared with multiple argument types, the adapter expects the payload to be a wshrpc.MultiArg struct (a struct wrapping an Args slice) and type-asserts the decoded payload to it. If the payload does not implement/convert to MultiArg, this error is returned. It protects the variadic-style RPC commands from receiving a single raw value.
Source
Thrown at pkg/wshutil/wshadapter.go:119
var callParams []reflect.Value
callParams = append(callParams, reflect.ValueOf(handler.Context()))
commandDataTypes := methodDecl.GetCommandDataTypes()
if len(commandDataTypes) == 1 {
cmdData, err := recodeCommandData(cmd, handler.GetCommandRawData(), commandDataTypes[0])
if err != nil {
handler.SendResponseError(err)
return true
}
callParams = append(callParams, reflect.ValueOf(cmdData))
} else if len(commandDataTypes) > 1 {
multiArgAny, err := recodeCommandData(cmd, handler.GetCommandRawData(), multiArgRType)
if err != nil {
handler.SendResponseError(err)
return true
}
multiArg, ok := multiArgAny.(wshrpc.MultiArg)
if !ok {
handler.SendResponseError(fmt.Errorf("command %q invalid multi arg payload", cmd))
return true
}
if len(multiArg.Args) != len(commandDataTypes) {
handler.SendResponseError(fmt.Errorf("command %q expected %d args, got %d", cmd, len(commandDataTypes), len(multiArg.Args)))
return true
}
for idx, commandDataType := range commandDataTypes {
cmdData, err := recodeCommandData(cmd, multiArg.Args[idx], commandDataType)
if err != nil {
handler.SendResponseError(err)
return true
}
callParams = append(callParams, reflect.ValueOf(cmdData))
}
}
if methodDecl.CommandType == wshrpc.RpcType_Call {
rtnVals := implMethod.Call(callParams)
rtnData, rtnErr := decodeRtnVals(rtnVals)View on GitHub (pinned to a4447c1563)
Solutions
- Wrap the arguments in wshrpc.MultiArg{Args: []any{arg1, arg2, ...}} with one entry per declared argument type.
- Check methodDecl.GetCommandDataTypes() for the command to confirm it is genuinely multi-arg before choosing a payload shape.
- If the command now takes a single argument in your version, upgrade/downgrade so both sides agree on the declaration.
Example fix
// before: single raw value for a multi-arg command
payload := domainScope
// after: wrap in MultiArg
payload := wshrpc.MultiArg{Args: []any{domainScope, varName, value}} Defensive patterns
Strategy: type-guard
Validate before calling
// Only send MultiArg payloads to commands declared multi-arg
decl := wshutil.WshCommandDeclMap[cmd]
if decl != nil && len(decl.GetCommandDataTypes()) > 1 {
payload = wshrpc.MultiArg{Args: args}
} Type guard
func asMultiArg(v any) (*wshrpc.MultiArg, bool) {
ma, ok := v.(wshrpc.MultiArg)
if !ok { return nil, false }
return &ma, true
} Try / catch
err := client.SendRpcRequest(ctx, cmd, payload)
if err != nil && strings.Contains(err.Error(), "invalid multi arg payload") {
return fmt.Errorf("%s requires wshrpc.MultiArg{Args: [...]}, got %T", cmd, payload)
} Prevention
- Wrap multiple arguments in wshrpc.MultiArg before sending.
- Check GetCommandDataTypes() for the command to learn the required arity and types.
- Write helper constructors per command instead of hand-building payloads.
When it happens
Trigger: Calling a multi-argument command (methodDecl has >1 command data types) with a plain payload instead of wshrpc.MultiArg{Args: [...]}; sending a single arg directly rather than wrapped in the Args slice.
Common situations: Hand-building RPC payloads in scripts or tests for commands like SetDomainVar/AppendDomainVar that take multiple typed args; forgetting the MultiArg wrapper after changing a command from single-arg to multi-arg.
Related errors
- error re-marshalling command data: %w
- command not implemented %q
- command %q expected %d args, got %d
- command %q not implemented
- command %q not found
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/aa1a1006cc47fdfc.
Report an issue: GitHub.