larksuite/cli · error

%T is not assignable to %s

Error message

%T is not assignable to %s

What it means

This error fires in reflectValue when a caller-supplied value's Go type can neither be assigned to nor converted to the target field type (e.g. a string where an int is required). The binder only auto-converts between compatible kinds; anything else is rejected with this message naming the actual %T and target type. It protects the compiled typed-field pipeline from silently mis-typed inputs.

Source

Thrown at shortcuts/common/typed_binder.go:292

	if err != nil {
		return err
	}
	target.Set(converted)
	return nil
}

func reflectValue(value any, target reflect.Type) (reflect.Value, error) {
	if value == nil {
		return reflect.Zero(target), nil
	}
	v := reflect.ValueOf(value)
	if v.Type().AssignableTo(target) {
		return v, nil
	}
	if v.Type().ConvertibleTo(target) {
		return v.Convert(target), nil
	}
	return reflect.Value{}, fmt.Errorf("%T is not assignable to %s", value, target)
}

func validateCompiledValue(value any, field compiledInputField) error {
	if value == nil {
		if err := validateJSONValueAgainstShape(nil, field.shape, "value"); err != nil {
			return typedFieldValidation(field, "%v", err).WithCause(err)
		}
		return nil
	}
	shape := field.shape
	if one, ok := shape.(typedOneOfShape); ok {
		for _, variant := range one.Variants {
			if _, null := variant.(typedNullShape); !null {
				shape = variant
				break
			}
		}
	}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Cast the value to the declared field type before passing it (strconv.Atoi for numeric strings).
  2. Check the target field's declared type in the compiled schema and supply a value of that Go type.
  3. If the value arrives as JSON, decode with the target type (json.Unmarshal into the typed variable) instead of reusing a generic interface{}.

Example fix

// before
binder.Set("timeout", "30") // string into int field

// after
n, err := strconv.Atoi("30")
if err != nil { return err }
binder.Set("timeout", n)
Defensive patterns

Strategy: type-guard

Validate before calling

func checkFieldKind(v any, want reflect.Kind) bool { return reflect.ValueOf(v).Kind() == want }

Try / catch

if err := binder.Set("timeout", raw); err != nil {
    if strings.Contains(err.Error(), "is not assignable to") {
        return fmt.Errorf("field %q needs a matching Go type, got %T", "timeout", raw)
    }
    return err
}

Prevention

When it happens

Trigger: Passing a value of an incompatible Go kind to a typed field — e.g. a string "123" for an int field, a map for a string field, a struct where a scalar is declared, or a bool where a number is expected via assignCompiledField.

Common situations: Config parsed from YAML/JSON keeps numbers as float64 or strings; developers hand those directly to the binder instead of casting. Also happens when a shortcut option is wired to the wrong typed field, or after a field type change upstream.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/f1c07e7c10d4e7cc. Report an issue: GitHub.