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

  1. Check the name for typos and confirm a matching template exists at layouts/_shortcodes/<name>.html (or in the theme).
  2. Ensure the theme/module providing the shortcode is actually installed and enabled ('hugo mod graph', check theme in config).
  3. 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

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


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/10ee2f8a81b9b049.json. Report an issue: GitHub ↗.