larksuite/cli · error
value is incompatible with %s: %w
Error message
value is incompatible with %s: %w
What it means
valueAssignableTo round-trips the default value through JSON (Marshal then Unmarshal into a reflect.New(target)) to prove it is compatible with the declared target type. If Unmarshal fails, this error wraps the JSON error with the target type name, indicating the default's shape does not fit the field's Go type.
Source
Thrown at shortcuts/common/typed_compile_args.go:641
if base.Kind() == reflect.Array && value != nil {
source := reflect.ValueOf(value)
for source.Kind() == reflect.Pointer || source.Kind() == reflect.Interface {
if source.IsNil() {
break
}
source = source.Elem()
}
if (source.Kind() == reflect.Array || source.Kind() == reflect.Slice) && source.Len() != base.Len() {
return fmt.Errorf("array default for %s requires exactly %d items, got %d", target, base.Len(), source.Len())
}
}
encoded, err := json.Marshal(value)
if err != nil {
return err
}
decoded := reflect.New(target)
if err := json.Unmarshal(encoded, decoded.Interface()); err != nil {
return fmt.Errorf("value is incompatible with %s: %w", target, err)
}
return nil
}
View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Align the default value with the field's Go type (e.g. numeric default for int fields, array for slices)
- Check the wrapped json error (%w cause) for the exact offset/type mismatch
- If the field uses a named type, ensure its JSON unmarshal accepts the default
Example fix
// before
type in struct{ Count int `cli:"default=many"` }
// after
type in struct{ Count int `cli:"default=3"` } Defensive patterns
Strategy: type-guard
Validate before calling
func defaultAssignable(value any, target reflect.Type) error {
encoded, err := json.Marshal(value)
if err != nil { return err }
return json.Unmarshal(encoded, reflect.New(target).Interface())
} Type guard
func canUnmarshalAs(value any, target reflect.Type) bool {
encoded, err := json.Marshal(value)
if err != nil { return false }
return json.Unmarshal(encoded, reflect.New(target).Interface()) == nil
} Try / catch
if err := valueAssignableTo(def, fieldType); err != nil {
var jsonErr *json.UnmarshalTypeError
if errors.As(err, &jsonErr) { log.Fatalf("default %v does not fit %s at %s", def, jsonErr.Type, jsonErr.Field) }
return err
} Prevention
- Update defaults whenever a field's type changes
- Prefer typed Go values over raw JSON strings for defaults
- Add a round-trip marshal/unmarshal test per default value
When it happens
Trigger: Assigning a default like a string to an int field, an object to a scalar, or a value that cannot unmarshal into a named type with a custom UnmarshalJSON rejecting it.
Common situations: Type drift after refactoring a field's type without updating its default; defaults written as untyped JSON strings/numbers that do not fit the declared Go type.
Related errors
- array default for %s requires exactly %d items, got %d
- ErrMalformedConfig
- protocol encode: %w
- protocol decode type: %w
- expected object, got %v
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/3ee9126ebaf3bf15.
Report an issue: GitHub.