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
- Cast the value to the declared field type before passing it (strconv.Atoi for numeric strings).
- Check the target field's declared type in the compiled schema and supply a value of that Go type.
- 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
- Decode JSON directly into typed variables instead of reusing interface{} maps.
- Consult `schema` output for each field's declared type before binding.
- Normalize config values (strings to numbers) in one boundary function.
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
- %v overflows %s
- %s must be a string
- not numeric
- Args must be a non-pointer struct, got %s
- Args field %s flag --%s duplicates %s
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/f1c07e7c10d4e7cc.
Report an issue: GitHub.