gohugoio/hugo · error

unable to convert value of type

Error message

unable to convert value of type %q to %q

What it means

Returned by hreflect's errConvert helper when ToInt64E/ToFloat64E/ToStringE cannot convert a reflect.Value to the requested target type. ConvertIfPossible only handles int/uint/float/string cross-conversions losslessly; any other kind (struct, slice, map, bool, complex, channel, func) yields this error naming both the source type and the target kind.

Solutions

  1. Pre-check the reflect.Kind before calling; handle non-convertible kinds explicitly.
  2. For uint64 sources, guard against overflow (> MaxInt64) before converting to int64.
  3. If you need a string of a struct, marshal to JSON instead of relying on ToStringE.

Example fix

// before
i, err := hreflect.ToInt64E(reflect.ValueOf(myStruct))
// after
if v.Kind() == reflect.Struct {
  b,_ := json.Marshal(v.Interface())
  // use string(b)
} else {
  i, err := hreflect.ToInt64E(v)
}
Defensive patterns

Strategy: type-guard

Validate before calling

func convertibleTo(rv reflect.Value, kind reflect.Kind) bool {
  switch rv.Kind() {
  case reflect.Bool, reflect.String, reflect.Struct, reflect.Map, reflect.Slice, reflect.Array, reflect.Chan, reflect.Func: return false
  }
  return true
}

Type guard

func isNumericOrString(rv reflect.Value) bool {
  k := rv.Kind()
  return hreflect.IsInt(k) || hreflect.IsUint(k) || hreflect.IsFloat(k) || hreflect.IsString(k)
}

Prevention

When it happens

Trigger: Calling hreflect.ToInt64E/ToFloat64E/ToStringE with a reflect.Value whose Kind is bool, struct, slice, map, or a numeric that would overflow the target (e.g. uint64 > MaxInt64).

Common situations: Reflection-based template helpers trying to stringify or numerify a structured value from frontmatter, or converting a large unsigned integer produced by the YAML decoder (see Issue 14079) into an int64 that overflows.

Related errors


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

Appendix: source

Thrown at common/hreflect/convert.go:88

func ToStringValueE(v reflect.Value) (reflect.Value, error) {
	if v, ok := ConvertIfPossible(v, typeString); ok {
		return v, nil
	}
	return reflect.Value{}, errConvert(v, "string")
}

// ToString converts v to string if possible, panicking if not.
func ToString(v reflect.Value) string {
	vv, err := ToStringE(v)
	if err != nil {
		panic(err)
	}
	return vv
}

func errConvert(v reflect.Value, s string) error {
	return fmt.Errorf("unable to convert value of type %q to %q", v.Type().String(), s)
}

// ConvertIfPossible tries to convert val to typ if possible.
// This is currently only implemented for int kinds,
// added to handle the move to a new YAML library which produces uint64 for unsigned integers.
// We can expand on this later if needed.
// This conversion is lossless.
// See Issue 14079.
func ConvertIfPossible(val reflect.Value, typ reflect.Type) (reflect.Value, bool) {
	switch val.Kind() {
	case reflect.Pointer, reflect.Interface:
		if val.IsNil() {
			// Return typ's zero value.
			return reflect.Zero(typ), true
		}
		val = val.Elem()
	}

View on GitHub (pinned to 52c9bd7908)