wavetermdev/waveterm · error

cannot convert argument %s.%s type:%T idx:%d error:%v

Error message

cannot convert argument %s.%s type:%T idx:%d error:%v

What it means

Each positional argument from webCall.Args is converted from its JSON (interface{}) form to the method's declared parameter type via convertArgument. This error wraps the failure of that conversion: the JSON value's type/shape does not match the parameter type (e.g. a string where a number, a non-object where a struct, or malformed JSON for a typed field).

Source

Thrown at pkg/service/service.go:346

	for idx := 0; idx < method.Type().NumIn(); idx++ {
		argType := method.Type().In(idx)
		if idx == 0 && argType == contextRType {
			valueArgs = append(valueArgs, reflect.ValueOf(ctx))
			continue
		}
		if argType == uiContextRType {
			if webCall.UIContext == nil {
				return webErrorRtn(fmt.Errorf("missing UIContext for %s.%s", webCall.Service, webCall.Method))
			}
			valueArgs = append(valueArgs, reflect.ValueOf(*webCall.UIContext))
			continue
		}
		if argIdx >= len(webCall.Args) {
			return webErrorRtn(fmt.Errorf("not enough arguments passed %s.%s idx:%d (type %T)", webCall.Service, webCall.Method, idx, argType))
		}
		nativeArg, err := convertArgument(argType, webCall.Args[argIdx])
		if err != nil {
			return webErrorRtn(fmt.Errorf("cannot convert argument %s.%s type:%T idx:%d error:%v", webCall.Service, webCall.Method, argType, idx, err))
		}
		valueArgs = append(valueArgs, reflect.ValueOf(nativeArg))
		argIdx++
	}
	retValArr := method.Call(valueArgs)
	return convertReturnValues(retValArr)
}

// ValidateServiceArg validates the argument type for a service method
// does not allow interfaces (and the obvious invalid types)
// arguments + return values have special handling for wave objects
func baseValidateServiceArg(argType reflect.Type) error {
	if argType == waveObjUpdateRType {
		// has special MarshalJSON method, so it is safe
		return nil
	}
	switch argType.Kind() {
	case reflect.Ptr, reflect.Slice, reflect.Array:

View on GitHub (pinned to a4447c1563)

Solutions

  1. Match each arg's JSON type to the method signature: string->string, number->int/float64, boolean->bool, object->struct, and fix the caller's payload
  2. Look at the wrapped %v error and the idx/type in the message to pinpoint the offending argument and its expected Go type
  3. Regenerate the TypeScript client so argument types are enforced at compile time in the frontend
  4. For struct parameters, ensure the JSON object's fields marshal to the Go struct (field names via the Go JSON tags)

Example fix

// before
Args: ["123", "true"] // strings where int and bool expected
// after
Args: [123, true]
Defensive patterns

Strategy: validation

Validate before calling

function assertArgTypes(call, expected) {
  call.Args.forEach((arg, i) => {
    const t = expected[i];
    if (t === "number" && typeof arg !== "number") throw new Error(`arg ${i}: expected number, got ${typeof arg}`);
    if (t === "string" && typeof arg !== "string") throw new Error(`arg ${i}: expected string, got ${typeof arg}`);
    if (t === "boolean" && typeof arg !== "boolean") throw new Error(`arg ${i}: expected boolean, got ${typeof arg}`);
  });
}

Type guard

function isArgOf<T>(arg: unknown, chk: (a: unknown) => a is T): arg is T { return chk(arg); }
const isNum = (a: unknown): a is number => typeof a === "number" && !isNaN(a);

Try / catch

const rtn = CallService(ctx, call);
if (rtn.Error.startsWith("cannot convert argument")) {
  const idx = parseInt(rtn.Error.match(/idx:(\d+)/)?.[1] ?? "-1", 10);
  console.error(`bad argument at position ${idx - offset}:`, call.Args[idx]);
}

Prevention

When it happens

Trigger: Passing an argument of the wrong JSON type — e.g. sending a string "123" where an int is required, a number where a bool is required, or an object missing required fields for a struct parameter; also nested type mismatches inside struct args.

Common situations: Hand-written RPC calls with untyped JSON (JavaScript numbers-as-strings); frontend sending null for non-pointer parameters; schema drift where the frontend still sends the old field format for a struct argument; locale/encoding issues corrupting string args.

Related errors


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