gohugoio/hugo · error
%s: shortcode %q does not evaluate .Inner or .InnerDeindent,
Error message
%s: shortcode %q does not evaluate .Inner or .InnerDeindent, yet a closing tag was provided
What it means
Hugo inspects each shortcode template at parse time to see whether it references .Inner or .InnerDeindent. If the template does not, the shortcode is treated as standalone, and encountering a closing tag ({{< /name >}}) for it in content is an error: the parser would otherwise swallow the enclosed content and silently drop it. This check makes the content/template mismatch explicit.
Source
Thrown at hugolib/shortcode.go:650
if !sc.templ.ParseInfo.IsInner {
return sc, nil
}
}
case currItem.IsShortcodeClose():
closed = true
next := pt.Peek()
if !sc.isInline {
if !sc.needsInner() {
if next.IsError() {
// return that error, more specific
continue
}
name := sc.name
if name == "" {
name = next.ValStr(source)
}
return nil, fmt.Errorf("%s: shortcode %q does not evaluate .Inner or .InnerDeindent, yet a closing tag was provided", errorPrefix, name)
}
}
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.View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Change the content to the self-closed/standalone form: {{< name >}} or {{< name />}} with no closing tag.
- If the shortcode should wrap content, add a use of .Inner (or .InnerDeindent) to layouts/_shortcodes/name.html.
- If .Inner is consumed indirectly (e.g. passed to a partial), reference it directly in the shortcode template so Hugo's parse-info detection sees it.
Example fix
{{/* before: layouts/_shortcodes/note.html */}}
<div class="note">Note</div>
{{/* after */}}
<div class="note">{{ .Inner | markdownify }}</div> Defensive patterns
Strategy: validation
Validate before calling
// Check the template uses .Inner before using paired syntax
// grep -l '\.Inner' layouts/_shortcodes/<name>.html || echo 'use self-closing {{< name />}}' Prevention
- Use paired {{< name >}}...{{< /name >}} only when the template evaluates .Inner or .InnerDeindent
- Switch to self-closing {{< name />}} for shortcodes that take no body
- When authoring a shortcode meant to wrap content, reference .Inner even if only to discard it deliberately
When it happens
Trigger: Content uses the paired form {{< name >}}...{{< /name >}} but layouts/_shortcodes/name.html never accesses .Inner or .InnerDeindent (needsInner() is false during extractShortcode). Only applies to non-inline shortcodes; inline shortcodes are exempt from the check.
Common situations: Refactoring a shortcode template and removing its .Inner usage while content still uses closing tags; using a theme's shortcode with the wrong calling convention; .Inner referenced only behind a construct the parser can't detect, or accessed via a partial rather than directly in the shortcode template.
Related errors
- failed to render shortcode %q: %w
- no earlier definition of shortcode %q found
- shortcode has no name
- %s: template for shortcode %q not found
- %s: shortcode %q must be closed or self-closed
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/cd8d67770a5be1d9.json.
Report an issue: GitHub ↗.