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
hreflect's errConvert is returned when ToStringValueE (and siblings) cannot convert a reflect.Value to the requested type. ConvertIfPossible only performs lossless conversions currently implemented for integer kinds (added for the new YAML library that decodes unsigned ints as uint64, see issue 14079); any value whose type can't be losslessly converted to the target — e.g. a map, slice, or float where a string is required — produces this error.
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 8a468df065)
Solutions
- Convert the value explicitly in the template (`string`, `int`) or fix the type at the data/config source.
- Check the error's quoted types to see what Hugo received vs. what it needed, and adjust the offending front matter/config key.
- If it appeared after a Hugo upgrade, check the changelog around YAML decoding (issue 14079) — quote values that must be strings.
Example fix
# before (front matter) version: 2.0 # decoded as float # after version: "2.0" # string as the template expects
Defensive patterns
Strategy: type-guard
Validate before calling
// Check convertibility before asking for a conversion
if !reflect.TypeOf(v).ConvertibleTo(target) { /* handle explicitly */ } Type guard
func convertibleTo(v any, target reflect.Type) bool {
t := reflect.TypeOf(v)
return t != nil && (t.AssignableTo(target) || t.ConvertibleTo(target))
} Try / catch
out, err := hreflect.ConvertTo(v, target)
if err != nil {
// incompatible types: the error names both — fix the source data or choose a different target
} Prevention
- Don't rely on implicit conversion between unrelated types (e.g. map → int); convert explicitly at the boundary.
- Normalize data-file values to the expected type in the data itself rather than coercing at render time.
- Type-switch on the handful of shapes you actually accept and reject the rest with a clear message.
When it happens
Trigger: Internal conversions where Hugo needs a specific type from a reflected value: e.g. a template or config path that requires a string but receives a map/slice/number that ConvertIfPossible can't handle, or an integer that would lose precision converting to the target type.
Common situations: Front matter/config values of the wrong type after the YAML library migration (uint64 vs int), passing complex values (maps, slices) where a string is expected in template function arguments, or data files supplying a number where Hugo requires a string.
Related errors
- failed to parse file %q: %s
- failed to unmarshal config for path %q: %w
- failed to load config: %w
- failed to load translations: %w%s
- failed to detect format from content
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/83f2d38def6b3616.json.
Report an issue: GitHub ↗.