gohugoio/hugo · error
unable to cast %#v of type %T to []map[string]interface
Error message
unable to cast %#v of type %T to []map[string]interface{} What it means
Returned by hmaps.ToSliceStringMap when the input is not one of the supported shapes ([]map[string]any, Params, map[string]any, or []any). The function normalizes heterogeneous config/frontmatter into a slice of maps; any other Go type falls through to the default branch and yields this error with the value and its type.
Solutions
- Re-shape the input to []map[string]any or []any whose elements are map[string]any.
- If you have map[string]string, convert via ToStringMapE first.
- Validate the decoded structure with a type assertion before calling ToSliceStringMap.
Example fix
// before
hmaps.ToSliceStringMap([]string{"a","b"})
// after
m := []map[string]any{{"value":"a"},{"value":"b"}}
hmaps.ToSliceStringMap(m) Defensive patterns
Strategy: type-guard
Validate before calling
func isSliceStringMapable(v any) bool {
switch v.(type) {
case []map[string]any, hmaps.Params, map[string]any, []any, nil: return true
}
return false
} Type guard
func isSliceStringMapable(v any) bool { _, ok := v.([]map[string]any); return ok || isSliceStringMapable(v) } Prevention
- Decode config into []map[string]any directly rather than generic any.
- Validate decoded structures with type switches before calling ToSliceStringMap.
When it happens
Trigger: Calling ToSliceStringMap with a struct, a []string, a number, `map[string]string`, or any type not in the switch arms of maps.go:95-113.
Common situations: Decoding menu entries, output-format definitions, or taxonomy params where the YAML/TOML decoded type does not match the expected nested-map shape (e.g. a scalar where a list of maps was expected).
Related errors
- --appendPort=false not supported when in multihost mode
- cache dir contains unresolved placeholders
- can't slice item of type
- cannot 3-index slice a string
- cannot append slice of
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/5f99470d0f4648f2.
Report an issue: GitHub.
Appendix: source
Thrown at common/hmaps/maps.go:112
// ToSliceStringMap converts in to []map[string]interface{}.
func ToSliceStringMap(in any) ([]map[string]any, error) {
switch v := in.(type) {
case []map[string]any:
return v, nil
case Params:
return []map[string]any{v}, nil
case map[string]any:
return []map[string]any{v}, nil
case []any:
var s []map[string]any
for _, entry := range v {
if vv, ok := entry.(map[string]any); ok {
s = append(s, vv)
}
}
return s, nil
default:
return nil, fmt.Errorf("unable to cast %#v of type %T to []map[string]interface{}", in, in)
}
}
// LookupEqualFold finds key in m with case insensitive equality checks.
func LookupEqualFold[T any | string](m map[string]T, key string) (T, string, bool) {
if v, found := m[key]; found {
return v, key, true
}
for k, v := range m {
if strings.EqualFold(k, key) {
return v, k, true
}
}
var s T
return s, "", false
}
// MergeShallow merges src into dst, but only if the key does not already exist in dst.View on GitHub (pinned to 52c9bd7908)