gohugoio/hugo · error
html/template: %q is undefined
Error message
html/template: %q is undefined
What it means
Returned by lookupAndEscapeTemplate (used by ExecuteTemplate) when no template with the given name exists in the set (t.set[name] == nil). html/template requires the target template to be associated with the caller before it can be executed. The %q is the requested name.
Source
Thrown at tpl/internal/go_templates/htmltemplate/template.go:152
// executions share a Writer the output may be interleaved.
func (t *Template) ExecuteTemplate(wr io.Writer, name string, data any) error {
tmpl, err := t.lookupAndEscapeTemplate(name)
if err != nil {
return err
}
return tmpl.text.Execute(wr, data)
}
// lookupAndEscapeTemplate guarantees that the template with the given name
// is escaped, or returns an error if it cannot be. It returns the named
// template.
func (t *Template) lookupAndEscapeTemplate(name string) (tmpl *Template, err error) {
t.nameSpace.mu.Lock()
defer t.nameSpace.mu.Unlock()
t.nameSpace.escaped = true
tmpl = t.set[name]
if tmpl == nil {
return nil, fmt.Errorf("html/template: %q is undefined", name)
}
if tmpl.escapeErr != nil && tmpl.escapeErr != escapeOK {
return nil, tmpl.escapeErr
}
if tmpl.text.Tree == nil || tmpl.text.Root == nil {
return nil, fmt.Errorf("html/template: %q is an incomplete template", name)
}
if t.text.Lookup(name) == nil {
panic("html/template internal error: template escaping out of sync")
}
if tmpl.escapeErr == nil {
err = escapeTemplate(tmpl, tmpl.text.Root, name)
}
return tmpl, err
}
// DefinedTemplates returns a string listing the defined templates,
// prefixed by the string "; defined templates are: ". If there are none,View on GitHub (pinned to 52c9bd7908)
Solutions
- Verify the exact name passed to ExecuteTemplate matches a {{define}} name or a parsed file's base name in the same set.
- Call t.Lookup(name) before ExecuteTemplate and fail with a clear message if nil.
- Ensure all partials are parsed into the same template set (associate via t.Parse of shared definitions or t.New).
- List defined templates via t.Templates() / t.DefinedTemplates() to confirm available names.
Example fix
// before
err := t.ExecuteTemplate(w, "page", data) // error: "page" undefined
// after
if t.Lookup("page") == nil {
return fmt.Errorf("page not in set; have: %s", t.DefinedTemplates())
}
err := t.ExecuteTemplate(w, "page", data) Defensive patterns
Strategy: validation
Validate before calling
func executeNamed(t *template.Template, name string, w io.Writer, data any) error {
if t.Lookup(name) == nil {
return fmt.Errorf("template %q undefined; available:%s", name, t.DefinedTemplates())
}
return t.ExecuteTemplate(w, name, data)
} Try / catch
if err := t.ExecuteTemplate(w, name, data); err != nil {
if strings.Contains(err.Error(), "is undefined") {
// fall back to a known default template
return t.ExecuteTemplate(w, defaultName, data)
}
return err
} Prevention
- Lookup before ExecuteTemplate and include DefinedTemplates() in the error.
- Keep all partials in one associated set.
- Use exact base names matching {{define}} names.
When it happens
Trigger: Calling ExecuteTemplate(w, name, data) where name does not match any template registered in the same association set (never defined, typo, or defined in a different template set).
Common situations: Typo in the layout/partial name; referencing a partial that lives in a different template set; using a base name vs full path mismatch; templates parsed into separate New() sets rather than one associated set.
Related errors
- html/template: %q is an incomplete template
- template: no template %q associated with template %q
- html/template: cannot Clone %q after it has executed
- html/template: cannot Parse after Execute
- template: %q is an incomplete or empty template
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/55ddddf3b80857b8.
Report an issue: GitHub.