gohugoio/hugo · error
unrecognized render hook template
Error message
unrecognized render hook template
What it means
Templates under a `_markup` directory are render hooks, and Hugo requires their filenames to start with the `render-` prefix (e.g. render-link.html, render-image.html) so it can derive the hook kind (Variant1/Variant2) from the name. A file in _markup whose name lacks that prefix cannot be classified, and template-store insertion fails with this error.
Source
Thrown at tpl/tplimpl/templatestore.go:1900
}
d.LayoutFromTemplate = ""
}
if d.LayoutFromTemplate == d.Kind {
d.LayoutFromTemplate = ""
}
k1 = strings.TrimPrefix(k1, "/_default")
if k1 == "/" {
k1 = ""
}
if category == CategoryMarkup {
// We store all template nodes for a given directory on the same level.
k1 = strings.TrimSuffix(k1, "/_markup")
v, found := strings.CutPrefix(d.LayoutFromTemplate, "render-")
if !found {
return "", "", 0, TemplateDescriptor{}, nil, fmt.Errorf("unrecognized render hook template")
}
hyphenIdx := strings.Index(v, "-")
d.Variant1 = v
if hyphenIdx > 0 {
d.Variant1 = v[:hyphenIdx]
d.Variant2 = v[hyphenIdx+1:]
}
d.LayoutFromTemplate = "" // This allows using page layout as part of the key for lookups.
}
return k1, k2, category, d, vactorStore, nil
}
func (s *TemplateStore) transformTemplates() error {
lookup := func(name string, in *TemplInfo) *TemplInfo {
if in.D.IsPlainText {View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Rename the file to the render-<kind>[-<variant>] convention, e.g. layouts/_markup/render-link.html or render-codeblock-mermaid.html.
- Move non-hook helper templates out of the _markup directory (put partials under layouts/_partials/).
- Delete editor backup/temp files accidentally left inside _markup.
Example fix
# before layouts/_markup/link.html # after layouts/_markup/render-link.html
Defensive patterns
Strategy: validation
Validate before calling
# render hooks must live under a recognized path/name ls layouts/_markup/ # e.g. render-link.html, render-image.html, render-heading.html, render-codeblock-<lang>.html
Prevention
- Name render hooks exactly render-link, render-image, render-heading, render-blockquote, render-passthrough, render-table, or render-codeblock[-lang]
- Place them under layouts/_markup/ (current spec), not arbitrary directories
- Don't invent custom render-* names — only the documented hook kinds are recognized
- After upgrading Hugo, re-check hook naming against the current docs since recognized names evolve
When it happens
Trigger: Placing any template in layouts/_markup/ (or layouts/**/_markup/) whose base name does not begin with `render-`, e.g. layouts/_markup/link.html or layouts/_markup/render_link.html (underscore instead of hyphen).
Common situations: Misremembering the naming convention (link.html instead of render-link.html); using an underscore (render_codeblock.html); stray helper partials or backup files (render-link.html.bak, foo.html) saved inside _markup; migrating from older layouts where hooks lived elsewhere.
Related errors
- project config markup.goldmark.renderHooks.image.useEmbedded
- project config markup.goldmark.renderHooks.link.useEmbedded
- no code renderer found for %q
- text is already rendered, repeating it may cause infinite re
- error building site: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/ea015ca32d30f80a.json.
Report an issue: GitHub ↗.