gohugoio/hugo · error
no template found for shortcode
Error message
no template found for shortcode %q
What it means
During shortcode lookup, Hugo walks the shortcode template tree (treeShortcodes) for the page path and shortcode name. When no candidate template is found at all (best.w.w1 <= 0 and candidatesAsStringSlice() returns nil), it reports 'no template found for shortcode %q'. This differs from the 'no compatible template' variant which fires when candidates exist but none match the descriptor (templatestore.go:688-696).
Solutions
- Verify the exact shortcode name spelling in both the markdown content and the template filename.
- Ensure the template file lives at layouts/shortcodes/<name>.html (or the theme equivalent).
- Check that the shortcode isn't only defined in a theme that was removed or not added via theme setup.
- Note shortcode names are lowercased — avoid relying on case to distinguish templates.
Example fix
// before — content references undefined shortcode
{{< mygraph src="x" >}}
// after — create layouts/shortcodes/mygraph.html
<figure><img src="{{ .Get "src" }}"></figure> Defensive patterns
Strategy: validation
Validate before calling
// Before building, verify every shortcode referenced in content has a template
// Quick bash check (run from project root):
// grep -rhoE '{{</?[^ >]+|{{%[^%]+%' content/ | sort -u
// and ensure each name matches layouts/shortcodes/<name>.html Prevention
- Keep shortcode names lowercase and consistently spelled in content and templates.
- Place shortcode templates under layouts/shortcodes/ (or the theme's equivalent).
- When removing/changing a theme, audit content for shortcodes it provided.
When it happens
Trigger: Content uses a shortcode {{< foo >}} but no corresponding template file exists under layouts/shortcodes/foo.html (or any path-qualified variant). Called via LookupShortcode(TemplateQuery{Name: "foo", ...}) during page rendering.
Common situations: Typo in the shortcode name in markdown; shortcode template file placed in the wrong directory (e.g. layouts/partials instead of layouts/shortcodes); removed a theme that provided the shortcode without providing a local replacement; case mismatch (shortcode names are lowercased at templatestore.go:640).
Related errors
- error building site
- failed to render shortcode
- process
- : shortcode does not evaluate .Inner or .InnerDeindent, yet…
- shortcode has no name
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/0d9267e59aed9de8.
Report an issue: GitHub.
Appendix: source
Thrown at tpl/tplimpl/templatestore.go:695
isBetter := best.isBetter(weight, vv)
if isBetter {
best.updateValues(weight, k2, k, vv)
}
}
return false, nil
})
if best.w.w1 <= 0 {
var err error
if s := best.candidatesAsStringSlice(); s != nil {
msg := fmt.Sprintf("no compatible template found for shortcode %q in %s", q.Name, s)
if !q.Desc.IsPlainText {
msg += "; note that to use plain text template shortcodes in HTML you need to use the shortcode {{% delimiter"
}
err = errors.New(msg)
} else {
err = fmt.Errorf("no template found for shortcode %q", q.Name)
}
return nil, err
}
return best.templ, nil
}
// PrintDebug is for testing/debugging only.
func (s *TemplateStore) PrintDebug(prefix string, category Category, w io.Writer) {
if w == nil {
w = os.Stdout
}
printOne := func(key string, vv *TemplInfo) {
level := strings.Count(key, "/")
if category != vv.category {
return
}View on GitHub (pinned to 52c9bd7908)