gohugoio/hugo · error

unable to convert value of type %q to %q

Error message

unable to convert value of type %q to %q

What it means

Thrown by convertNumber when hreflect.ConvertIfPossible cannot convert a numeric value to the target numeric type. convertNumber is the numeric branch of convertValue, used by set operations to reconcile e.g. int vs int64 vs float64 element types. Both source and target type names are quoted in the message.

Source

Thrown at tpl/collections/reflect_helpers.go:100

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()
		if tp.Kind() == reflect.Pointer {
			tp = tp.Elem()
		}

		return reflect.New(tp).Interface()
	}
	return nil
}

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Normalize element types to a standard kind (int, int64, float64) before the set operation.
  2. Avoid custom numeric types in slices passed to SymDiff.
  3. Map elements to plain int/float64 upstream.
  4. Check hreflect.ConvertIfPossible support for your specific types.

Example fix

// before
{{ symdiff $customIntSlice $int64Slice }}
// after
{{ symdiff $intSliceA $intSliceB }}
Defensive patterns

Strategy: validation

Validate before calling

func numericTypesConvertible(src, dst reflect.Type) bool {
    if !hreflect.IsNumber(src.Kind()) || !hreflect.IsNumber(dst.Kind()) { return false }
    _, ok := hreflect.ConvertIfPossible(reflect.Zero(src), dst)
    return ok
}

Type guard

func isStandardNumeric(t reflect.Type) bool {
    switch t.Kind() {
    case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
         reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
         reflect.Float32, reflect.Float64:
        return true
    }
    return false
}

Prevention

When it happens

Trigger: SymDiff (or another caller) where slices have numeric element types that hreflect refuses to convert — e.g. a custom numeric type that isn't directly convertible, or an edge case in numeric kind handling. The ConvertIfPossible fast-path returns false, falling through to the error.

Common situations: Custom typed integers/floats in data structures, or version changes where hreflect's conversion support narrowed. Relatively rare since standard numeric kinds usually convert.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/3430df68f9e56671. Report an issue: GitHub.