gohugoio/hugo · error
expected template, but none provided
Error message
expected template, but none provided
What it means
`applyTemplateTransformers` (tpl/tplimpl/templatetransform.go:77) is the internal pass that rewrites a parsed Hugo template (partial return handling, defer nodes, lookups). It guards against being handed a nil `*TemplInfo`; a nil here means an upstream lookup or parse produced no template. This is an internal invariant error, not a user-facing template syntax error.
Source
Thrown at tpl/tplimpl/templatetransform.go:77
lookupFn func(name string, in *TemplInfo) *TemplInfo,
) *templateTransformContext {
return &templateTransformContext{
t: t,
lookupFn: lookupFn,
store: store,
visited: make(map[string]bool),
templateNotFound: make(map[string]bool),
deferNodes: make(map[string]*parse.ListNode),
}
}
func applyTemplateTransformers(
t *TemplInfo,
store *TemplateStore,
lookupFn func(name string, in *TemplInfo) *TemplInfo,
) (*templateTransformContext, error) {
if t == nil {
return nil, errors.New("expected template, but none provided")
}
c := newTemplateTransformContext(t, store, lookupFn)
c.t.ParseInfo = defaultParseInfo
tree := getParseTree(t.Template)
if tree == nil {
panic(fmt.Errorf("template %s not parsed", t))
}
if err := c.applyTransformationsAndSetReturnWrapper(tree); err != nil {
return c, fmt.Errorf("failed to transform template %q: %w", t.Name(), err)
}
return c, c.err
}
func getParseTree(templ tpl.Template) *parse.Tree {
if text, ok := templ.(*texttemplate.Template); ok {View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Upgrade to the latest Hugo release; if it persists, this is likely an internal bug.
- Run `hugo --logLevel debug` to identify which template/layout triggers the transform and try removing or simplifying it to isolate the trigger.
- Report the issue to gohugo.io/GitHub with the minimal reproducing layouts, since this error signals an internal invariant violation.
- If embedding hugolib programmatically, ensure you never pass a nil template into the template store APIs.
Defensive patterns
Strategy: validation
Validate before calling
{{/* never call template/partial helpers with an empty name */}}
{{ $name := .Params.layoutPartial }}
{{ if and $name (templates.Exists (printf "partials/%s" $name)) }}
{{ partial $name . }}
{{ end }} Prevention
- Ensure every layout/partial file you reference actually contains template content, not an empty file
- Guard dynamically computed template names against empty strings before invoking them
- After upgrading Hugo, run a full build — empty or stub templates that previously passed may now be rejected
- Delete placeholder zero-byte template files from layouts/ instead of leaving them to be parsed
When it happens
Trigger: Hugo's template store invoking the transformer chain with a nil TemplInfo — e.g. a template that failed to parse or a lookup path that returned nil being passed into the transform stage. End users cannot trigger it directly through template functions.
Common situations: Almost always indicates a Hugo bug or a broken template store state — e.g. after a regression in the 0.146+ template store rewrite, an unusual layouts arrangement exposing an unhandled lookup path, or a custom fork/embedding of hugolib passing nil templates. Rarely seen in normal site builds.
Related errors
- template %s not parsed
- conf must be set
- error building site: %w
- npm pack: failed to marshal package.json with updated worksp
- failed to detect format from content
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/25b070309e42b5ec.json.
Report an issue: GitHub ↗.