gohugoio/hugo · error

failed to transform template %q: %w

Error message

failed to transform template %q: %w

What it means

Wrapper error returned when Hugo's template transformation pass fails for a specific template. After parsing, Hugo rewrites the parse tree (partial return-value wrapping, templates.Defer handling, partial decorators); any error from those transformations is wrapped with the template's name so the failing layout/partial is identifiable.

Source

Thrown at tpl/tplimpl/templatetransform.go:88

func applyTemplateTransformers(
	t *TemplInfo,
	store *TemplateStore,
	lookupFn func(name string, in *TemplInfo) *TemplInfo,
) (*templateTransformContext, error) {
	if t == nil {
		return nil, errors.New("expected template, but none provided")
	}

	c := newTemplateTransformContext(t, store, lookupFn)
	c.t.ParseInfo = defaultParseInfo
	tree := getParseTree(t.Template)
	if tree == nil {
		panic(fmt.Errorf("template %s not parsed", t))
	}

	if err := c.applyTransformationsAndSetReturnWrapper(tree); err != nil {
		return c, fmt.Errorf("failed to transform template %q: %w", t.Name(), err)
	}

	return c, c.err
}

func getParseTree(templ tpl.Template) *parse.Tree {
	if text, ok := templ.(*texttemplate.Template); ok {
		return text.Tree
	}
	return templ.(*htmltemplate.Template).Tree
}

const (
	// We parse this template and modify the nodes in order to assign
	// the return value of a partial to a contextWrapper via Set. We use
	// "range" over a one-element slice so we can shift dot to the
	// partial's argument, Arg, while allowing Arg to be falsy.
	partialReturnWrapperTempl = `{{ $_hugo_dot := $ }}{{ $ := .Arg }}{{ range (slice .Arg) }}{{ $_hugo_dot.Set ("PLACEHOLDER") }}{{ end }}`

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Read the wrapped inner error — it names the actual rule violated — and fix that construct in the named template.
  2. Open the template named in %q and review recent changes to Defer/partial/with usage.
  3. Check the Hugo docs for templates.Defer and partial decorator constraints matching the inner error.
  4. Re-run 'hugo' to confirm the template transforms cleanly.
Defensive patterns

Strategy: try-catch

Try / catch

# Treat this as a build-time syntax failure: run
hugo build --logLevel debug
# and fix the template named in %q; the wrapped %w shows the parse/transform cause

Prevention

When it happens

Trigger: applyTransformationsAndSetReturnWrapper returns an error for template %q — e.g. malformed use of templates.Defer, partial decorator constructs, or inner/with misuse detected during tree rewriting (see errors 152/153, which surface wrapped by this one).

Common situations: Appears at build time after editing a layout or partial that uses templates.Defer, {{ with (partial ...) }} decorator patterns, or block/inner constructs; also after upgrading Hugo when transformation rules tightened.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/a7b97b2e2f2b1e2b.json. Report an issue: GitHub ↗.