gohugoio/hugo · error

no earlier definition of shortcode

Error message

no earlier definition of shortcode %q found

What it means

Raised in doRenderShortcode (shortcode.go:399) for an inline shortcode used without a closing tag. Inline shortcodes ({{< myshort >}} without a closing {{< /myshort >}}) must reference a definition that appeared earlier in the same page; the code does ts.TextLookup on the _inline_shortcode template path and, if nil, reports no earlier definition.

Solutions

  1. Define the inline shortcode earlier in the same page before calling its open form, or use the closing-tag form {{< name >}}body{{< /name >}} at the call site.
  2. Ensure the call-site name exactly matches the definition name.
  3. Consider moving the shortcode to layouts/shortcodes if it is reused across pages.

Example fix

{{/* before: call before definition */}}
{{< greeting >}}
...
{{< greeting >}}Hello{{< /greeting >}}

{{/* after: define first */}}
{{< greeting >}}Hello{{< /greeting >}}
...
{{< greeting >}}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Using {{< myinline >}} (open form) before the {{< myinline >}}...{{< /myinline >}} definition that creates it; referencing an inline shortcode name that was never defined on the page; enableInlineShortcodes disabled would silently return zero, so this specifically means the lookup found nothing for a closing-less reference.

Common situations: Reordering content so a call appears before its inline definition; renaming an inline shortcode in one place but not the call site; copy-pasting an inline shortcode call from another page where it was defined.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/4963ccffddcf7a41. Report an issue: GitHub.

Appendix: source

Thrown at hugolib/shortcode.go:399

			var err error
			tmpl, err = ts.TextParse(templatePath, templStr)
			if err != nil {
				if isRenderString {
					return zeroShortcode, p.wrapError(err)
				}
				fe := herrors.NewFileErrorFromName(err, p.File().Filename())
				pos := fe.Position()
				pos.LineNumber += p.posOffset(sc.pos).LineNumber
				fe = fe.UpdatePosition(pos)
				return zeroShortcode, p.wrapError(fe)
			}

		} else {
			// Re-use of shortcode defined earlier in the same page.
			tmpl = ts.TextLookup(templatePath)
			if tmpl == nil {
				return zeroShortcode, fmt.Errorf("no earlier definition of shortcode %q found", sc.name)
			}
		}
	} else {
		ofCount := map[string]int{}
		include := func(match *tplimpl.TemplInfo) bool {
			ofCount[match.D.OutputFormat]++
			return true
		}
		base, layoutDescriptor := po.GetInternalTemplateBasePathAndDescriptor()

		// With shortcodes/mymarkdown.md (only), this allows {{% mymarkdown %}} when rendering HTML,
		// but will not resolve any template when doing {{< mymarkdown >}}.
		layoutDescriptor.AlwaysAllowPlainText = sc.doMarkup
		q := tplimpl.TemplateQuery{
			Path:     base,
			Name:     sc.name,
			Category: tplimpl.CategoryShortcode,
			Desc:     layoutDescriptor,

View on GitHub (pinned to 52c9bd7908)