{"record":{"id":"ea015ca32d30f80a","repo":"gohugoio/hugo","slug":"unrecognized-render-hook-template","errorCode":null,"errorMessage":"unrecognized render hook template","messagePattern":"unrecognized render hook template","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/tplimpl/templatestore.go","lineNumber":1900,"sourceCode":"\t\t}\n\t\td.LayoutFromTemplate = \"\"\n\t}\n\n\tif d.LayoutFromTemplate == d.Kind {\n\t\td.LayoutFromTemplate = \"\"\n\t}\n\n\tk1 = strings.TrimPrefix(k1, \"/_default\")\n\tif k1 == \"/\" {\n\t\tk1 = \"\"\n\t}\n\n\tif category == CategoryMarkup {\n\t\t// We store all template nodes for a given directory on the same level.\n\t\tk1 = strings.TrimSuffix(k1, \"/_markup\")\n\t\tv, found := strings.CutPrefix(d.LayoutFromTemplate, \"render-\")\n\t\tif !found {\n\t\t\treturn \"\", \"\", 0, TemplateDescriptor{}, nil, fmt.Errorf(\"unrecognized render hook template\")\n\t\t}\n\t\thyphenIdx := strings.Index(v, \"-\")\n\n\t\td.Variant1 = v\n\t\tif hyphenIdx > 0 {\n\t\t\td.Variant1 = v[:hyphenIdx]\n\t\t\td.Variant2 = v[hyphenIdx+1:]\n\t\t}\n\n\t\td.LayoutFromTemplate = \"\" // This allows using page layout as part of the key for lookups.\n\t}\n\n\treturn k1, k2, category, d, vactorStore, nil\n}\n\nfunc (s *TemplateStore) transformTemplates() error {\n\tlookup := func(name string, in *TemplInfo) *TemplInfo {\n\t\tif in.D.IsPlainText {","sourceCodeStart":1882,"sourceCodeEnd":1918,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/tplimpl/templatestore.go#L1882-L1918","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlayouts/_markup/link.html\n\n// after\nlayouts/_markup/render-link.html","handlingStrategy":"validation","validationCode":"// Before adding a file under layouts/_markup/, confirm its name starts with 'render-'\n// Supported: render-link.html, render-image.html, render-heading.html,\n//            render-codeblock-*.html, etc.\n// If it's not a render hook, place it under layouts/partials/ instead.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["render-hook","markup","template-naming","build","configuration"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}