gohugoio/hugo · error
no earlier definition of shortcode %q found
Error message
no earlier definition of shortcode %q found
What it means
Inline shortcodes ({{< name.inline >}}...{{< /name.inline >}}) define their template body in the content file on first use; subsequent uses of {{< name.inline />}} without a body reuse that earlier definition, looked up under a per-page template path. If Hugo can't find a previously parsed definition with that name on the same page, it fails with this error, because there is no template body to execute.
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 8a468df065)
Solutions
- Add or move the full defining occurrence ({{< name.inline >}}...{{< /name.inline >}}) before any self-closed reuse on the same page.
- If the logic is shared across pages, convert it to a regular shortcode file under layouts/_shortcodes/ instead of an inline shortcode.
- Confirm 'security.enableInlineShortcodes = true' is set — with it off inline shortcodes render empty, but naming/order errors like this still indicate the definition is missing.
Example fix
<!-- before (content/post.md) -->
{{< greet.inline />}}
{{< greet.inline >}}Hello {{ .Get 0 }}{{< /greet.inline >}}
<!-- after -->
{{< greet.inline >}}Hello {{ .Get 0 }}{{< /greet.inline >}}
{{< greet.inline />}} Defensive patterns
Strategy: validation
Validate before calling
// Before overriding, confirm the shortcode exists upstream
// e.g. check themes/<theme>/layouts/_shortcodes/<name>.html exists
if _, err := os.Stat(filepath.Join(themeDir, "layouts/_shortcodes", name+".html")); err != nil {
return fmt.Errorf("no base shortcode %q to inherit from", name)
} Prevention
- Only call template inheritance from a shortcode that actually overrides a theme/base shortcode of the same name
- Verify the shortcode name matches the upstream file name exactly
- Check the theme's layouts/_shortcodes directory before writing an override that delegates upward
When it happens
Trigger: Using a self-closed inline shortcode ({{< foo.inline />}}) before — or without — a closed defining occurrence ({{< foo.inline >}}body{{< /foo.inline >}}) earlier in the same page. Inline shortcode definitions are scoped per page (templatePath includes p.Path()), so a definition on another page does not count.
Common situations: Reordering content so the self-closed reuse appears above the definition; expecting inline shortcode definitions to be shared across pages or from an archetype; copy-pasting only the reuse call; using them in .RenderString contexts without the definition.
Related errors
- shortcode has no name
- %s: shortcode %q does not evaluate .Inner or .InnerDeindent,
- %s: template for shortcode %q not found
- %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/4963ccffddcf7a41.json.
Report an issue: GitHub ↗.