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

  1. Report a Hugo bug with the content/layout that reproduces it
  2. Ensure any custom contentNode implementation satisfies the expected type set
  3. 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

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


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/7ebbb619329f680f. Report an issue: GitHub.