gohugoio/hugo · error
: template for shortcode not found
Error message
%s: template for shortcode %q not found
What it means
Raised in extractShortcode (shortcode.go:671) during the parsing of a shortcode name token: s.firstTemplateStore.LookupShortcodeByName returns nil, meaning no shortcode template with that name is registered in any template store reachable from the page. This fires at parse time, before rendering, while Hugo decides whether the shortcode expects inner content.
Solutions
- Create layouts/shortcodes/<name>.html (or .amber/.ace per your template engine) in the project or theme.
- Correct the shortcode name in the content to match an existing template exactly (case-sensitive).
- Ensure the theme providing the shortcode is listed under `theme`/`module.imports` and mounted.
Example fix
{{/* before: no such shortcode */}}
{{< greeeting >}}
{{/* after */}}
{{< greeting >}}
# and create layouts/shortcodes/greeting.html Defensive patterns
Strategy: validation
Validate before calling
# Verify every shortcode name used in content has a template.
used=$(grep -rhoE '\{\{[%<][[:space:]]*[a-zA-Z0-9_-]+' content | sed -E 's/.*[[:space:]]+//' | sort -u)
for name in $used; do
find layouts -path "*/shortcodes/${name}.html" | grep -q . || echo "missing shortcode template: $name"
done Prevention
- Keep a project convention: every shortcode name maps 1:1 to layouts/shortcodes/<name>.html.
- When switching themes, copy custom shortcodes or add shim templates.
- Run the shortcode/template audit above in CI.
When it happens
Trigger: Using {{< foo >}} when no layouts/shortcodes/foo.html (or theme equivalent) exists; a typo in the shortcode name; the shortcode lives only in a theme that is not mounted; output-format/language mismatch so the lookup set excludes the only defining template.
Common situations: Switching themes and forgetting to migrate custom shortcodes; content referencing a shortcode that was renamed/removed; theme not added to hugo.toml; shortcode names with case differences (shortcode names are case-sensitive in lookup).
Related errors
- failed to render shortcode
- failed to render shortcode
- no earlier definition of shortcode
- : shortcode does not evaluate .Inner or .InnerDeindent, yet…
- alignx must be one of left, center, right
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/10ee2f8a81b9b049.
Report an issue: GitHub.
Appendix: 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 52c9bd7908)