{"record":{"id":"4c21504a0b745dfb","repo":"wavetermdev/waveterm","slug":"not-enough-arguments-passed-s-s-idx-d-type-t","errorCode":null,"errorMessage":"not enough arguments passed %s.%s idx:%d (type %T)","messagePattern":"not enough arguments passed (.+?)\\.(.+?) idx:(.+?) \\(type %T\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/service/service.go","lineNumber":342,"sourceCode":"\t\treturn webErrorRtn(fmt.Errorf(\"invalid method: %s.%s\", webCall.Service, webCall.Method))\n\t}\n\tvar valueArgs []reflect.Value\n\targIdx := 0\n\tfor idx := 0; idx < method.Type().NumIn(); idx++ {\n\t\targType := method.Type().In(idx)\n\t\tif idx == 0 && argType == contextRType {\n\t\t\tvalueArgs = append(valueArgs, reflect.ValueOf(ctx))\n\t\t\tcontinue\n\t\t}\n\t\tif argType == uiContextRType {\n\t\t\tif webCall.UIContext == nil {\n\t\t\t\treturn webErrorRtn(fmt.Errorf(\"missing UIContext for %s.%s\", webCall.Service, webCall.Method))\n\t\t\t}\n\t\t\tvalueArgs = append(valueArgs, reflect.ValueOf(*webCall.UIContext))\n\t\t\tcontinue\n\t\t}\n\t\tif argIdx >= len(webCall.Args) {\n\t\t\treturn webErrorRtn(fmt.Errorf(\"not enough arguments passed %s.%s idx:%d (type %T)\", webCall.Service, webCall.Method, idx, argType))\n\t\t}\n\t\tnativeArg, err := convertArgument(argType, webCall.Args[argIdx])\n\t\tif err != nil {\n\t\t\treturn webErrorRtn(fmt.Errorf(\"cannot convert argument %s.%s type:%T idx:%d error:%v\", webCall.Service, webCall.Method, argType, idx, err))\n\t\t}\n\t\tvalueArgs = append(valueArgs, reflect.ValueOf(nativeArg))\n\t\targIdx++\n\t}\n\tretValArr := method.Call(valueArgs)\n\treturn convertReturnValues(retValArr)\n}\n\n// ValidateServiceArg validates the argument type for a service method\n// does not allow interfaces (and the obvious invalid types)\n// arguments + return values have special handling for wave objects\nfunc baseValidateServiceArg(argType reflect.Type) error {\n\tif argType == waveObjUpdateRType {\n\t\t// has special MarshalJSON method, so it is safe","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/service/service.go#L324-L360","documentation":"CallService maps the method's declared parameters (skipping context.Context and UIContext) onto the JSON args array in webCall.Args one by one. This error is returned when the method requires more positional arguments than the request supplied, i.e. argIdx ran past len(webCall.Args) while parameter idx still needed a value.","triggerScenarios":"Sending fewer JSON args than the service method's non-context, non-UIContext parameter count — e.g. CreateWorkspace(ctx, name, icon, color, applyDefaults) called with only 2 args, or a call using an outdated arg count after the method gained a parameter.","commonSituations":"Frontend/backend version skew after a service method gained a new parameter; hand-built RPC payloads in tests or scripts omitting trailing args; variadic-vs-fixed arg confusion; boolean/optional trailing parameters assumed skippable.","solutions":["Supply all required positional arguments in webCall.Args in the method's declared order (excluding ctx/UIContext)","Regenerate/refresh the TypeScript client (tsgen) so arg counts match the backend signatures","If a parameter is genuinely optional, extend the method or pass an explicit zero value (e.g. false for bool, \"\" for string)","Read the idx and type in the message to see exactly which parameter (position, counting ctx) was missing"],"exampleFix":"// before\nCallService(ctx, WebCallType{Service: \"workspace\", Method: \"CreateWorkspace\", Args: [\"my-ws\"]})\n// after\nCallService(ctx, WebCallType{Service: \"workspace\", Method: \"CreateWorkspace\", Args: [\"my-ws\", \"terminal\", \"blue\", true]})","handlingStrategy":"validation","validationCode":"const minArgs = { CreateWorkspace: 4, UpdateWorkspace: 5, CreateWindow: 2 };\nfunction hasEnoughArgs(service, method, args) {\n  const n = minArgs[method];\n  return n == null || Array.isArray(args) && args.length >= n;\n}","typeGuard":"function argsMatchArity<N extends number>(args: unknown[], n: N): args is { length: N } & unknown[] {\n  return args.length >= n;\n}","tryCatchPattern":"const rtn = CallService(ctx, call);\nif (rtn.Error.startsWith(\"not enough arguments\")) {\n  console.error(`arity error for ${call.Service}.${call.Method}:`, rtn.Error);\n  // regenerate client / fix arg list\n}","preventionTips":["Use the generated typed client so arity is checked at compile time","Regenerate tsgen output whenever a service method signature changes","Count args as method params minus leading ctx (and UIContext) when hand-building calls"],"tags":["rpc","arguments","arity"],"backgroundTag":"rpc-argument-count-mismatch","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}