gohugoio/hugo · error
%s: template for shortcode %q not found
Error message
%s: template for shortcode %q not found
What it means
During shortcode extraction, as soon as the parser reads a shortcode's name it looks up any template with that name (LookupShortcodeByName) to learn whether it expects inner content. If no shortcode template with that name exists anywhere in the project, themes, or Hugo's embedded templates, extraction fails with this error — the shortcode simply isn't defined.
Source
Thrown at hugolib/shortcode.go:671
if next.IsRightShortcodeDelim() {
// self-closing
pt.Consume(1)
} else {
sc.isClosing = true
pt.Consume(2)
}
return sc, nil
case currItem.IsText():
sc.inner = append(sc.inner, currItem.ValStr(source))
case currItem.IsShortcodeName():
sc.name = currItem.ValStr(source)
// Used to check if the template expects inner content,
// so just pick one arbitrarily with the same name.
templ := s.firstTemplateStore.LookupShortcodeByName(sc.name)
if templ == nil {
return nil, fmt.Errorf("%s: template for shortcode %q not found", errorPrefix, sc.name)
}
sc.templ = templ
case currItem.IsInlineShortcodeName():
sc.name = currItem.ValStr(source)
sc.isInline = true
case currItem.IsShortcodeParam():
if !pt.IsValueNext() {
continue
} else if pt.Peek().IsShortcodeParamVal() {
// named params
if sc.params == nil {
params := make(map[string]any)
params[currItem.ValStr(source)] = pt.Next().ValTyped(source)
sc.params = params
} else {
if params, ok := sc.params.(map[string]any); ok {
params[currItem.ValStr(source)] = pt.Next().ValTyped(source)
} else {View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Check the name for typos and confirm a matching template exists at layouts/_shortcodes/<name>.html (or in the theme).
- Ensure the theme/module providing the shortcode is actually installed and enabled ('hugo mod graph', check theme in config).
- Create the missing shortcode template, or remove/escape the call ({{</* name */>}}) if it's documentation of syntax.
Example fix
<!-- before: content uses {{< alert >}} but no template exists -->
{{/* after: create layouts/_shortcodes/alert.html */}}
<div class="alert">{{ .Inner }}</div> Defensive patterns
Strategy: validation
Validate before calling
// Verify the shortcode template exists in the lookup path // test -f layouts/_shortcodes/<name>.html || test -f themes/<theme>/layouts/_shortcodes/<name>.html
Try / catch
if err := h.Build(cfg); err != nil {
if strings.Contains(err.Error(), "template for shortcode") {
// list available shortcodes to diagnose typos
}
return err
} Prevention
- Match the shortcode call name exactly to the template filename (case-sensitive on Linux)
- Place custom shortcodes in layouts/_shortcodes/ (current spec), not stale paths
- Remember embedded shortcodes (figure, highlight, ref) exist only if not disabled; check theme provides the rest
- Escape literal shortcode syntax in docs with {{</* name */>}}
When it happens
Trigger: Content calling {{< name >}} / {{% name %}} where no layouts/_shortcodes/name.* (or legacy layouts/shortcodes/name.*) template exists in the project, any mounted module/theme, or Hugo's built-ins.
Common situations: Typos in the shortcode name; theme not installed or module mount missing so the theme's shortcodes are absent; migrating content between sites that used different custom shortcodes; using a shortcode removed in a Hugo upgrade; unescaped example shortcode syntax in docs content.
Related errors
- no earlier definition of shortcode %q found
- shortcode has no name
- %s: shortcode %q does not evaluate .Inner or .InnerDeindent,
- %s: shortcode %q must be closed or self-closed
- error processing file %q
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/10ee2f8a81b9b049.json.
Report an issue: GitHub ↗.