{"record":{"id":"4321ac9c12b0c691","repo":"wavetermdev/waveterm","slug":"invalid-argument-type-s","errorCode":null,"errorMessage":"invalid argument type %s","messagePattern":"invalid argument type (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/service/service.go","lineNumber":262,"sourceCode":"\t\treturn convertComplex(argType, jsonArg)\n\n\tcase reflect.Struct:\n\t\tif jsonType.Kind() != reflect.Map {\n\t\t\treturn nil, fmt.Errorf(\"cannot convert %T to %s\", jsonArg, argType)\n\t\t}\n\t\treturn convertComplex(argType, jsonArg)\n\n\tcase reflect.Ptr:\n\t\tif argType.Elem().Kind() != reflect.Struct {\n\t\t\treturn nil, fmt.Errorf(\"invalid pointer type %s\", argType)\n\t\t}\n\t\tif jsonType.Kind() != reflect.Map {\n\t\t\treturn nil, fmt.Errorf(\"cannot convert %T to %s\", jsonArg, argType)\n\t\t}\n\t\treturn convertComplex(argType, jsonArg)\n\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid argument type %s\", argType)\n\t}\n}\n\nfunc isNilable(val reflect.Value) bool {\n\tswitch val.Kind() {\n\tcase reflect.Ptr, reflect.Slice, reflect.Map, reflect.Interface, reflect.Chan, reflect.Func:\n\t\treturn true\n\t}\n\treturn false\n\n}\n\nfunc convertReturnValues(rtnVals []reflect.Value) *WebReturnType {\n\trtn := &WebReturnType{}\n\tif len(rtnVals) == 0 {\n\t\treturn rtn\n\t}\n\tfor _, val := range rtnVals {","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/service/service.go#L244-L280","documentation":"Thrown by convertArgument's default branch when a service method parameter's reflect.Kind is one the RPC bridge does not support at all (anything outside String, Bool, numeric, Map, Slice, Struct, Ptr, and special wave arg types) — e.g. channels, funcs, interfaces, complex numbers, or unsafe pointers.","triggerScenarios":"Calling a service method whose signature includes a chan, func, interface{}, complex, or other exotic parameter type; the error fires on any call attempt regardless of the JSON value passed.","commonSituations":"Adding a callback or channel parameter to an existing service method and exposing it over RPC; using interface{} parameters assuming the bridge passes raw JSON through.","solutions":["Remove the unsupported parameter type from the service method signature.","Replace func/chan params with event subscriptions or ids usable with the pubsub system.","For dynamic payloads, use a supported type such as map[string]any or a struct instead of interface{}.","If the type is actually a Wave special type (WaveObj etc.), make it match isSpecialWaveArgType's recognized types so it routes through convertSpecial."],"exampleFix":"// before\nfunc (s *Svc) Watch(ch chan int) error\n\n// after\nfunc (s *Svc) Watch(scope string) error { // subscribe via WPS events\n    ...\n}","handlingStrategy":"validation","validationCode":"// audit the Go signature: supported kinds are string,bool,numbers,map,slice,struct,*struct + special wave types\nconst supported = new Set(['string','bool','number','object','array']);\nif (!supported.has(typeof arg)) throw new Error('arg type unsupported by RPC bridge');","typeGuard":null,"tryCatchPattern":"try {\n  const rtn = await callService(svc, method, args);\n  if (rtn.error?.includes('invalid argument type')) throw new Error('method signature has an unsupported parameter kind');\n} catch (e) { /* the method itself must be redesigned; no client-side fix */ }","preventionTips":["Never expose chan/func/interface{} parameters on RPC services.","Use map[string]any or structs for dynamic payloads.","Add a registration-time check that walks each service method's parameter kinds."],"tags":["rpc","unsupported-type","reflection","signature"],"backgroundTag":"rpc-unsupported-parameter-type","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}