gohugoio/hugo · error
language merge not supported for %T
Error message
language merge not supported for %T
What it means
`lang.Merge` unions page collections across languages by requiring the first collection (p1) to implement Hugo's internal `pagesLanguageMerger` interface (`MergeByLanguageInterface`). Only Hugo Pages collections implement it; if p1 is any other type (a plain slice, map, string, etc.), Hugo returns this error with the offending type.
Source
Thrown at tpl/lang/lang.go:246
return string(b), nil
}
type pagesLanguageMerger interface {
MergeByLanguageInterface(other any) (any, error)
}
// Merge creates a union of pages from two languages.
func (ns *Namespace) Merge(p2, p1 any) (any, error) {
if !hreflect.IsTruthful(p1) {
return p2, nil
}
if !hreflect.IsTruthful(p2) {
return p1, nil
}
merger, ok := p1.(pagesLanguageMerger)
if !ok {
return nil, fmt.Errorf("language merge not supported for %T", p1)
}
return merger.MergeByLanguageInterface(p2)
}
View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Ensure both arguments are Pages collections, e.g. `{{ $merged := site.RegularPages | lang.Merge ((index site.Sites 1).RegularPages) }}`.
- If filtering first, use `where` directly on a Pages collection (which preserves the Pages type) rather than building a new slice with `slice`/`append` of mixed values.
- For non-page data, use `collections.Merge` or `append`/`union` instead — `lang.Merge` is only for pages across languages.
Example fix
<!-- before -->
{{ $merged := (slice $p1 $p2) | lang.Merge $frPages }}
<!-- after -->
{{ $merged := site.RegularPages | lang.Merge $frSite.RegularPages }} Defensive patterns
Strategy: type-guard
Validate before calling
{{ $v := site.Params.someMap }}
{{ if reflect.IsMap $v }}{{/* safe to merge language params */}}{{ end }} Type guard
{{ $isMergeable := reflect.IsMap $v }} Try / catch
{{ with try (merge $base $override) }}{{ with .Err }}{{ warnf "language merge failed: %s" . }}{{ else }}{{ .Value }}{{ end }}{{ end }} Prevention
- Only maps (params objects) can be merged across languages — check with reflect.IsMap first
- Keep the same param structure (map vs slice vs scalar) for a given key across all language configs
- Don't mix scalar and map values under the same params key in different language files
When it happens
Trigger: Calling `{{ $pages | lang.Merge $other }}` where the second (pipeline) argument is not a Hugo Pages collection — e.g. a `slice`, the result of `where` that produced a generic slice, a map, or a single Page. Note both arguments are checked for truthiness first, so an empty p1 skips the check.
Common situations: Multilingual sites where a template passes `.Site.Data` values, a plain `slice`, or a single `.Page` instead of `.Site.RegularPages`/`.Translations`-derived page collections; applying `lang.Merge` to results of `collections` functions that returned `[]interface{}` instead of Pages.
Related errors
- grouping not supported for type %T %T
- %T cannot be merged by language
- cannot convert type %T to Pages
- error building site: %w
- multihost change detected, please restart server
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/8781e61cdd7ae5a5.json.
Report an issue: GitHub ↗.