gohugoio/hugo · error
is not assignable to
Error message
%s is not assignable to %s
What it means
Thrown by convertValue when a value cannot be assigned to the target type and the target kind is neither string nor numeric (so neither ToStringValueE nor convertNumber applies). convertValue is used by set operations (e.g. SymDiff) to coerce elements to the result slice's element type. Both the source type and target type are named via %s.
Solutions
- Ensure both slices share a compatible element type before calling SymDiff.
- Map/transform elements to a common type (string or number) upstream.
- Avoid symdiff on slices of custom structs unless their types match.
- Inspect both types named in the error to find the incompatibility.
Example fix
// before
{{ symdiff $structSlice $intSlice }}
// after
{{ symdiff $intSliceA $intSliceB }} Defensive patterns
Strategy: type-guard
Validate before calling
func elementTypesCompatible(a, b reflect.Type) bool {
if a == b { return true }
if a.Kind() == reflect.String || b.Kind() == reflect.String { return true }
if hreflect.IsNumber(a.Kind()) && hreflect.IsNumber(b.Kind()) { return true }
return a.Kind() == reflect.Interface || b.Kind() == reflect.Interface
} Type guard
func isConvertibleType(t reflect.Type) bool {
return t.Kind() == reflect.String || hreflect.IsNumber(t.Kind())
} Prevention
- Ensure both set-operation slices share a compatible element type.
- Map heterogeneous elements to strings or numbers upstream.
- Avoid symdiff on slices of custom structs unless types match exactly.
- Inspect both types in the error to locate the incompatibility.
When it happens
Trigger: SymDiff (or another caller of convertValue) where the two input slices have element types that cannot be reconciled — e.g. symdiff a []struct against []int where the struct isn't string/number-coercible. The default branch of convertValue fires for non-string, non-number target kinds.
Common situations: Mixing slices of incompatible element types in set operations, or evolving a slice's element type during a refactor while old data remains. Less common than the slice/array type errors but arises with heterogeneous structs.
Related errors
- incompatible map types, got %T to %T
- symdiff: failed to convert value
- unable to convert value of type
- argument must be a slice
- arguments must be slices or arrays
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/13cffb8231449073.
Report an issue: GitHub.
Appendix: source
Thrown at tpl/collections/reflect_helpers.go:92
}
}
return seen, nil
}
// We have some different numeric and string types that we try to behave like
// they were the same.
func convertValue(v reflect.Value, to reflect.Type) (reflect.Value, error) {
if v.Type().AssignableTo(to) {
return v, nil
}
switch kind := to.Kind(); {
case kind == reflect.String:
return hreflect.ToStringValueE(v)
case hreflect.IsNumber(kind):
return convertNumber(v, to)
default:
return reflect.Value{}, fmt.Errorf("%s is not assignable to %s", v.Type(), to)
}
}
func convertNumber(v reflect.Value, typ reflect.Type) (reflect.Value, error) {
if v, ok := hreflect.ConvertIfPossible(v, typ); ok {
return v, nil
}
return reflect.Value{}, fmt.Errorf("unable to convert value of type %q to %q", v.Type().String(), typ.String())
}
func newSliceElement(items any) any {
tp := reflect.TypeOf(items)
if tp == nil {
return nil
}
switch tp.Kind() {
case reflect.Array, reflect.Slice:
tp = tp.Elem()View on GitHub (pinned to 52c9bd7908)