gohugoio/hugo · error

inner cannot be used inside a with block that wraps a…

Error message

inner cannot be used inside a with block that wraps a partial decorator

What it means

Hugo rewrites certain {{ with partial ... }} blocks into internal partial decorators (handleWithPartial, templatetransform.go:324-329). The regex templatesInnerRe detects a call to templates.Inner or inner inside the with-block's body; because the decorator machinery cannot correctly propagate the inner content in that position, Hugo rejects it explicitly rather than producing broken output.

Solutions

  1. Remove the {{ inner }} / {{ templates.Inner }} call from inside the {{ with partial ... }} block.
  2. Restructure so inner content is passed as a partial parameter or rendered outside the with-block.
  3. If you need partial-overridable blocks, use Hugo's block/define mechanism instead of with+inner.

Example fix

// before
{{ with partial "card" . }}
  {{ inner }}
{{ end }}

// after — pass content as a param, do not use inner in with-partial
{{ partial "card" (dict "ctx" . "content" .Inner) }}
Defensive patterns

Strategy: validation

Validate before calling

// In template authoring, never use {{ inner }} or {{ templates.Inner }} inside
// a {{ with partial ... }} ... {{ end }} block. Pass content as a dict arg instead:
{{ partial "card" (dict "content" .Inner) }}

Prevention

When it happens

Trigger: Writing a template that uses {{ with partial "foo" . }}...{{ inner }}...{{ end }} or {{ templates.Inner }} inside the with-body that wraps a partial call. Detected by the regex `{{\s*(templates\.Inner\b|inner\b)` against the serialized with-node list.

Common situations: Trying to use the 'inner' mechanism (intended for shortcodes/decorators) inside a with-partial block; copying shortcode patterns into a partial layout; experimenting with advanced partial decorator features without understanding the constraint.

Related errors


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

Appendix: source

Thrown at tpl/tplimpl/templatetransform.go:327

		case *parse.WithNode:
			if c.hasBreakOrContinueOutsideRange(x.List) {
				return true
			}
			if c.hasBreakOrContinueOutsideRange(x.ElseList) {
				return true
			}
		case *parse.BreakNode, *parse.ContinueNode:
			return true

		}
	}
	return false
}

func (c *templateTransformContext) handleWithPartial(withNode *parse.WithNode) {
	withNodeInnerString := withNode.List.String()
	if templatesInnerRe.MatchString(withNodeInnerString) {
		c.err = fmt.Errorf("inner cannot be used inside a with block that wraps a partial decorator")
		return
	}

	// See #14333. That is a very odd construct, but we need to guard against it.
	if c.hasBreakOrContinueOutsideRange(withNode.List) {
		return
	}
	innerHash := hashing.XxHashFromStringHexEncoded(c.t.Name() + withNodeInnerString)
	internalPartialName := fmt.Sprintf("_partials/%s%s", PartialDecoratorPrefix, innerHash)

	if c.lookupFn(internalPartialName, c.t) == nil {
		innerCopy := withNode.List.CopyList()
		ti, err := c.store.addTransformedTemplateInsert(internalPartialName, SubCategoryInline)
		if err != nil {
			c.err = fmt.Errorf("failed to create internal partial decorator template %q: %w", internalPartialName, err)
			return
		}
		if ti == nil {

View on GitHub (pinned to 52c9bd7908)