gohugoio/hugo · error
unrecognized render hook template
Error message
unrecognized render hook template
What it means
Hugo categorizes templates under layouts/_markup/ as render-hook templates (CategoryMarkup). When extracting the template key (templatestore.go:1895-1901), it requires the layout name to begin with 'render-' (e.g. render-link, render-image) and uses strings.CutPrefix to split it off. If the prefix is absent, the template is not a recognized render hook and the error is returned. This catches misnamed files placed in the _markup directory.
Solutions
- Rename the file so it starts with 'render-', e.g. render-link.html, render-image.html, render-heading.html.
- If the file is not a render hook, move it out of the _markup directory (e.g. to layouts/partials/).
- Verify the filename against supported hooks: render-link, render-image, render-heading, render-codeblock, etc.
Example fix
// before layouts/_markup/link.html // after layouts/_markup/render-link.html
Defensive patterns
Strategy: validation
Validate before calling
// Before adding a file under layouts/_markup/, confirm its name starts with 'render-' // Supported: render-link.html, render-image.html, render-heading.html, // render-codeblock-*.html, etc. // If it's not a render hook, place it under layouts/partials/ instead.
Prevention
- Reserve layouts/_markup/ exclusively for render-hook templates named render-*.
- Keep helper templates in layouts/partials/.
- Cross-check filenames against the Hugo render-hooks documentation.
When it happens
Trigger: Placing a template file in layouts/_markup/ (or a theme equivalent) whose filename does not start with 'render-', e.g. layouts/_markup/link.html or layouts/_markup/foo.html. Encountered during template ingestion/key extraction.
Common situations: Misunderstanding the render-hook naming convention; renaming a render-link.html to something else; placing a non-render-hook helper template in _markup by mistake; old tutorials referencing pre-render-hook era filenames.
Related errors
- failed to resolve media type for
- failed to resolve media type for suffix
- no content renderer found for markup
- assemble
- babel config not found
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/ea015ca32d30f80a.
Report an issue: GitHub.
Appendix: 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 52c9bd7908)