gohugoio/hugo · error
failed to convert %T to a string slice
Error message
failed to convert %T to a string slice
What it means
Returned by types.ToStringSlicePreserveStringE when cast.ToStringSliceE fails and the reflect fallback also fails (value is not a string, slice, or array). The fallback iterates slice/array elements but any other Kind lands in the default branch and yields this error naming the Go type.
Solutions
- Supply a []string, []any, array, or a single string.
- If a scalar is intended, wrap it in []string{fmt.Sprint(v)}.
- Validate Kind==Slice/Array/String before calling.
Example fix
// before
types.ToStringSlicePreserveStringE(42)
// after
types.ToStringSlicePreserveStringE([]string{"42"}) Defensive patterns
Strategy: type-guard
Validate before calling
func isStringSliceable(v any) bool {
if v == nil { return true }
switch reflect.ValueOf(v).Kind() {
case reflect.String, reflect.Slice, reflect.Array: return true
}
return false
} Type guard
func isStringSliceable(v any) bool { k := reflect.ValueOf(v).Kind(); return k==reflect.String||k==reflect.Slice||k==reflect.Array } Prevention
- Wrap scalars in []string{fmt.Sprint(v)} before conversion.
- Type-check config list fields at decode time.
- Avoid passing structs/maps to ToStringSlicePreserveStringE.
When it happens
Trigger: Calling ToStringSlicePreserveStringE with a struct, map, number, bool, or pointer to non-slice. nil returns nil,nil; strings are wrapped; slices/arrays are element-wise stringified.
Common situations: Config fields expected to be lists but supplied as scalars (e.g. `menu.main.weight` instead of a list), or frontmatter where a YAML flow scalar replaces a sequence.
Related errors
- cannot convert to time.Duration
- --appendPort=false not supported when in multihost mode
- cache dir contains unresolved placeholders
- cannot determine BaseURL for protocol
- cannot unmarshal CSV into %T: invalid targetType: expected…
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/9a7654913c9d6220.
Report an issue: GitHub.
Appendix: source
Thrown at common/types/convert.go:81
return result, nil
}
// Probably []int or similar. Fall back to reflect.
vv := reflect.ValueOf(v)
switch vv.Kind() {
case reflect.Slice, reflect.Array:
result = make([]string, vv.Len())
for i := range vv.Len() {
s, err := cast.ToStringE(vv.Index(i).Interface())
if err != nil {
return nil, err
}
result[i] = s
}
return result, nil
default:
return nil, fmt.Errorf("failed to convert %T to a string slice", v)
}
}
// TypeToString converts v to a string if it's a valid string type.
// Note that this will not try to convert numeric values etc.,
// use ToString for that.
func TypeToString(v any) (string, bool) {
switch s := v.(type) {
case string:
return s, true
case template.HTML:
return string(s), true
case template.CSS:
return string(s), true
case template.HTMLAttr:
return string(s), true
case template.JS:
return string(s), trueView on GitHub (pinned to 52c9bd7908)