gohugoio/hugo · error

no layout given

Error message

no layout given

What it means

Thrown by pageContentOutput.Render in hugolib/page__per_output.go:109 when the variadic layout argument is empty. Render needs at least one layout/view name to look up the template to execute; with none it cannot proceed. This is the engine behind the .Render and .RenderShortcodes template methods.

Solutions

  1. Pass a concrete layout/view name, e.g. {{ .Render "summary" }} which resolves to layouts/_default/summary.html.
  2. If the layout name comes from a param, guard it: {{ with .Params.view }}{{ $.Render . }}{{ end }}.
  3. Verify the layout file exists under layouts/ (e.g. layouts/page.html or layouts/_default/<view>.html) after fixing the call.

Example fix

// before
{{ .Render }}
// after
{{ .Render "summary" }}
Defensive patterns

Strategy: validation

Validate before calling

// In a Go template, guard the layout name before calling Render.
{{ with .Params.view }}{{ $.Render . }}{{ else }}{{ $.Render "default" }}{{ end }}

Type guard

// Go callers: ensure at least one layout arg is present.
func hasLayout(layout ...string) bool { return len(layout) > 0 && layout[0] != "" }

Prevention

When it happens

Trigger: Calling {{ .Render }} (or .RenderString) in a template without passing a layout name, or invoking page.Render(ctx) with no layout arguments in Go. Also triggered when a shortcode/template delegates to .Render with a variable that resolves to an empty string.

Common situations: Forgetting the view argument in a baseof/block template, passing an unset page param as the layout name (e.g. {{ .Render .Params.view }} when view is blank), or refactoring a layout lookup and dropping the argument.

Related errors


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

Appendix: source

Thrown at hugolib/page__per_output.go:109

	renderHooks *renderHooks
}

func (pco *pageContentOutput) trackDependency(idp identity.IdentityProvider) {
	pco.po.p.dependencyManagerOutput.AddIdentity(idp.GetIdentity())
}

func (pco *pageContentOutput) Reset() {
	if pco == nil {
		return
	}
	pco.contentRenderedVersion++
	pco.contentRendered.Store(false)
	pco.renderHooks = &renderHooks{}
}

func (pco *pageContentOutput) Render(ctx context.Context, layout ...string) (template.HTML, error) {
	if len(layout) == 0 {
		return "", errors.New("no layout given")
	}
	templ, found, err := pco.po.p.resolveTemplate(layout...)
	if err != nil {
		return "", pco.po.p.wrapError(err)
	}

	if !found {
		return "", fmt.Errorf("template %q not found", layout[0])
	}

	// Make sure to send the *pageState and not the *pageContentOutput to the template.
	res, err := executeToString(ctx, pco.po.p.s.GetTemplateStore(), templ, pco.po.p)
	if err != nil {
		return "", pco.po.p.wrapError(fmt.Errorf("failed to execute template %s: %w", templ.Name(), err))
	}
	return template.HTML(res), nil
}

View on GitHub (pinned to 52c9bd7908)