gohugoio/hugo · error
partial %q not found
Error message
partial %q not found
What it means
Raised by the partials namespace lookup (tpl/partials/partials.go:140) when `partial` or `partialCached` is called with a name that `TemplateStore.LookupPartial` cannot resolve. Hugo looks partials up relative to `layouts/_partials/` (formerly `layouts/partials/`); if no template exists under that name, rendering fails with this error.
Source
Thrown at tpl/partials/partials.go:140
}
func (ns *Namespace) include(ctx context.Context, name string, dataList ...any) includeResult {
v, err := ns.lookup(name)
if err != nil {
return includeResult{err: err}
}
return ns.doInclude(ctx, "", v, dataList...)
}
func (ns *Namespace) lookup(name string) (*tplimpl.TemplInfo, error) {
if strings.HasPrefix(name, "partials/") {
// This is most likely not what the user intended.
// This worked before Hugo 0.146.0.
ns.deps.Log.Warnidf(constants.WarnPartialSuperfluousPrefix, "Doubtful use of partial function in {{ partial \"%s\"}}), this is most likely not what you want. Consider removing superfluous prefix \"partials/\" from template name given as first function argument.", name)
}
v := ns.deps.TemplateStore.LookupPartial(name)
if v == nil {
return nil, fmt.Errorf("partial %q not found", name)
}
return v, nil
}
// include is a helper function that lookups and executes the named partial.
// Returns the final template name and the rendered output.
func (ns *Namespace) doInclude(ctx context.Context, key string, templ *tplimpl.TemplInfo, dataList ...any) includeResult {
if templ.ParseInfo.HasPartialInner {
stack := tpl.Context.PartialDecoratorIDStack.Get(ctx)
if stack != nil {
if id, ok := stack.Peek(); ok {
// Signal that inner exists.
id.Bool = true
}
}
}
var data any
if len(dataList) > 0 {View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Verify the file exists at `layouts/_partials/<name>` (or `layouts/partials/` in older setups), matching case exactly.
- Remove any superfluous `partials/` prefix from the call: use `{{ partial "foo.html" . }}`, not `{{ partial "partials/foo.html" . }}`.
- If the partial comes from a theme or module, confirm the theme/module is listed in your site config and vendored/fetched (`hugo mod get`).
- Run `hugo --printPathWarnings` or check the site with `hugo server` to see lookup warnings.
Example fix
<!-- before -->
{{ partial "partials/head.html" . }}
<!-- after: file at layouts/_partials/head.html -->
{{ partial "head.html" . }} Defensive patterns
Strategy: validation
Validate before calling
{{ if templates.Exists (printf "partials/%s" $name) }}
{{ partial $name . }}
{{ else }}
{{ warnf "partial %q missing" $name }}
{{ end }} Prevention
- Guard dynamic partial names with templates.Exists before calling partial
- Keep partial paths relative to layouts/partials/ and include the file extension if the file has one
- Verify theme-provided partials exist when overriding or upgrading a theme
- Avoid constructing partial names from user content without a whitelist
When it happens
Trigger: `{{ partial "foo.html" . }}` or `{{ partialCached "foo.html" . }}` where `layouts/_partials/foo.html` (or a theme/module equivalent) does not exist; a typo in the name; wrong subdirectory path; or a missing file extension when one is required.
Common situations: Typos or case mismatches in the partial name (case matters on Linux/CI but not macOS), forgetting the theme or module that supplies the partial in `theme`/module imports, migrating to Hugo ≥ 0.146 where the layouts layout changed, or writing `partials/foo.html` as the argument — the code explicitly warns that the `partials/` prefix is superfluous and usually wrong.
Related errors
- circular call stack detected in partial %q
- inner cannot be used inside a with block that wraps a partia
- maximum template call stack size exceeded in %q
- template %q not found
- error building site: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/f559b9d373cd4280.json.
Report an issue: GitHub ↗.