wavetermdev/waveterm · error
cannot convert %T to %s
Error message
cannot convert %T to %s
What it means
convertWSCommand converts a JSON argument into a webcmd.WSCommand. The JSON value must be a map[string]any; any other JSON type (string, number, array, nil) cannot represent a command and triggers 'cannot convert %T to %s'.
Source
Thrown at pkg/service/service.go:104
return nil, fmt.Errorf("invalid number type %s", argType)
}
func convertComplex(argType reflect.Type, jsonArg any) (any, error) {
nativeArgVal := reflect.New(argType)
err := utilfn.DoMapStructure(nativeArgVal.Interface(), jsonArg)
if err != nil {
return nil, err
}
return nativeArgVal.Elem().Interface(), nil
}
func isSpecialWaveArgType(argType reflect.Type) bool {
return argType == waveObjRType || argType == waveObjSliceRType || argType == waveObjMapRType || argType == wsCommandRType
}
func convertWSCommand(argType reflect.Type, jsonArg any) (any, error) {
if _, ok := jsonArg.(map[string]any); !ok {
return nil, fmt.Errorf("cannot convert %T to %s", jsonArg, argType)
}
cmd, err := webcmd.ParseWSCommandMap(jsonArg.(map[string]any))
if err != nil {
return nil, fmt.Errorf("error parsing command map: %w", err)
}
return cmd, nil
}
func convertSpecial(argType reflect.Type, jsonArg any) (any, error) {
jsonType := reflect.TypeOf(jsonArg)
if argType == orefRType {
if jsonType.Kind() != reflect.String {
return nil, fmt.Errorf("cannot convert %T to %s", jsonArg, argType)
}
oref, err := waveobj.ParseORef(jsonArg.(string))
if err != nil {
return nil, fmt.Errorf("invalid oref string: %v", err)
}View on GitHub (pinned to a4447c1563)
Solutions
- Pass the command as a JSON object with the expected WSCommand fields (command, args, etc.).
- Wrap string command names into the proper object shape before invoking.
- Ensure client and server versions agree on the WSCommand argument shape.
Example fix
// before
invokeRpc("run-command", "run:shell")
// after
invokeRpc("run-command", map[string]any{"command": "run", "args": []any{"shell"}}) Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := arg.(map[string]any); !ok {
return fmt.Errorf("WSCommand arg must be a JSON object, got %T", arg)
} Type guard
func isWSCommandArg(v any) bool {
_, ok := v.(map[string]any)
return ok
} Prevention
- Serialize WSCommand from its struct via the SDK; never hand-build alternatives.
- Keep client and server argument schemas in sync via shared types.
- Add tests for every RPC invocation path.
When it happens
Trigger: An RPC method takes a WSCommand parameter but the caller passes a string (e.g. a command name) or array instead of a JSON object like {"command":"run","args":[...]}.
Common situations: Frontend sends the command as a serialized string instead of an object; callers confuse WSCommand with a command string ID; client/server schema drift.
Related errors
- invalid number type %s
- nil wshrpc passed to wshclient
- no default route
- response channel closed
- <resp.Error>
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/5376f2b8bcc03365.
Report an issue: GitHub.