gohugoio/hugo · error

: shortcode does not evaluate .Inner or .InnerDeindent, yet…

Error message

%s: shortcode %q does not evaluate .Inner or .InnerDeindent, yet a closing tag was provided

What it means

Raised in extractShortcode (shortcode.go:650) when a closing shortcode tag ({{< /name >}}) is encountered but the resolved shortcode template's ParseInfo.IsInner is false — meaning the template never reads .Inner or .InnerDeindent. Hugo treats closing tags as meaningful only for shortcodes that consume inner content; supplying one for a non-inner shortcode is an error.

Solutions

  1. Remove the closing tag for shortcodes whose templates do not use .Inner (use the self-closing form {{< name ... >}}).
  2. If inner content is intended, update the shortcode template to evaluate .Inner or .InnerDeindent.
  3. Check for typos in the closing tag name that resolve to a different (non-inner) shortcode.

Example fix

{{/* before: figure does not use .Inner */}}
{{< figure src="x.png" >}}caption{{< /figure >}}

{{/* after */}}
{{< figure src="x.png" >}}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Writing {{< highlight go >}}...{{< /highlight >}} is correct (highlight uses .Inner), but writing {{< figure src="x.png" >}}...{{< /figure >}} fails because figure does not use .Inner; closing a self-closing shortcode by habit; mismatched names where the opening tag resolved to a non-inner template.

Common situations: Habitually closing all shortcodes; using a closing tag on shortcodes ported from another system that required them; template changes that removed .Inner usage without updating content.

Related errors


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

Appendix: 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 52c9bd7908)