gohugoio/hugo · critical
contentNodeToContentNodesPage: unexpected type %T
Error message
contentNodeToContentNodesPage: unexpected type %T
What it means
An internal panic in contentNodeToContentNodesPage (hugolib/content_map_page_contentnode.go:395). The function narrows a contentNode to a contentNodesMap but only knows how to handle the concrete types contentNodesMap and *pageState; any other type triggers the panic. This is an invariant of Hugo's page content tree.
Source
Thrown at hugolib/content_map_page_contentnode.go:395
func (n contentNodesMap) isEmpty() bool {
return len(n) == 0
}
func absint(i int) int {
if i < 0 {
return -i
}
return i
}
func contentNodeToContentNodesPage(n contentNode) (contentNodesMap, bool) {
switch v := n.(type) {
case contentNodesMap:
return v, false
case *pageState:
return contentNodesMap{v.s.siteVector: v}, true
default:
panic(fmt.Sprintf("contentNodeToContentNodesPage: unexpected type %T", n))
}
}
// hasAutoContentNode reports whether n holds at least one node that is not backed by a file.
func (h helperContentNode) hasAutoContentNode(n contentNodeForEach) bool {
return !n.forEeachContentNode(func(_ sitesmatrix.Vector, nn contentNode) bool {
wp, ok := nn.(contentNodeContentWeightProvider)
return ok && wp.contentWeight() > 0
})
}
func (h helperContentNode) contentNodeToSeq(n contentNodeForEach) contentNodeSeq {
if nn, ok := n.(contentNodeSeq); ok {
return nn
}
return func(yield func(contentNode) bool) {
n.forEeachContentNode(func(_ sitesmatrix.Vector, nn contentNode) bool {
return yield(nn)View on GitHub (pinned to 52c9bd7908)
Solutions
- Report a Hugo bug with the content/layout that reproduces it
- Ensure any custom contentNode implementation satisfies the expected type set
- Upgrade to a released Hugo version rather than a custom build
Defensive patterns
Strategy: type-guard
Validate before calling
// Internal: ensure n is one of the handled types before narrowing.
switch n.(type) {
case contentNodesMap, *pageState:
default:
panic(fmt.Sprintf("unexpected contentNode type %T", n))
} Type guard
func isNarrowableContentNode(n contentNode) bool {
switch n.(type) {
case contentNodesMap, *pageState:
return true
}
return false
} Prevention
- This is an internal invariant; report bugs rather than working around them
- Keep custom contentNode implementations within the recognized type set
- Add unit tests covering all node types when extending the content map
When it happens
Trigger: A contentNode implementation other than contentNodesMap or *pageState is placed in the page tree and later narrowed. Not reachable through normal user content or configuration.
Common situations: Hugo internal bug, a broken intermediate build, or a custom hook/plugin injecting an unexpected node type. Almost exclusively seen during Hugo development.
Related errors
- no vectors
- DeleteFunc: unknown type %T
- Insert: unknown type %T
- Shift: unknown type %T for %q
- no site found for matrix %s
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/7ebbb619329f680f.
Report an issue: GitHub.