gohugoio/hugo · error
Defer does not take any arguments
Error message
Defer does not take any arguments
What it means
`templates.Defer` must be invoked with no positional arguments; it is designed to be used as `{{ with (templates.Defer) }}` or with options attached via a dict in the documented `(templates.Defer (dict ...))` form handled elsewhere — the validated call path here rejects any leftover args (tpl/templates/templates.go:68-70). The check exists because arguments passed positionally would be silently ignored, so Hugo fails fast instead.
Source
Thrown at tpl/templates/templates.go:69
func (ns *Namespace) Exists(name string) bool {
return ns.deps.GetTemplateStore().HasTemplate(name)
}
// Defer defers the execution of a template block.
func (ns *Namespace) Defer(ctx context.Context, args ...any) (bool, error) {
// Prevent defer from being used in content adapters,
// that just doesn't work.
ns.deps.Site.CheckReady()
// Reject use inside a partialCached body: the cached output retains the
// deferred placeholder across rebuilds while the executions map is reset,
// which used to cause a panic in executeDeferredTemplates. See issue #13492.
if tpl.Context.IsInPartialCached.Get(ctx) {
return false, fmt.Errorf("templates.Defer cannot be used inside a partialCached partial; use partial instead, or move templates.Defer to the calling template")
}
if len(args) != 0 {
return false, fmt.Errorf("Defer does not take any arguments")
}
return true, nil
}
var defferedIDCounter atomic.Uint64
type DeferOpts struct {
// Optional cache key. If set, the deferred block will be executed
// once per unique key.
Key string
// Optional data context to use when executing the deferred block.
Data any
}
// Inner executes the inner content of a partial decorator.
// Note that there is only one inner block per partial decorator, but inner may be called multiple times with, typically, different data.
func (ns *Namespace) Inner(ctx context.Context, data any) (any, error) {View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Remove the arguments: use `{{ with (templates.Defer) }}...{{ end }}`.
- To pass a key or data, use the documented options form: `{{ with (templates.Defer (dict "key" "global" "data" .)) }}` — inside the block, the data is available as the context.
- Consult the templates.Defer docs for the exact supported options (key, data).
Example fix
<!-- before -->
{{ with (templates.Defer .) }}...{{ end }}
<!-- after -->
{{ with (templates.Defer (dict "data" .)) }}...{{ end }} Defensive patterns
Strategy: validation
Validate before calling
{{/* correct usage — no arguments, options via with-block context: */}}
{{ with (templates.Defer (dict "key" "global")) }}...{{ end }}
{{/* wrong: {{ templates.Defer . }} */}} Prevention
- Call templates.Defer with zero positional arguments; pass options as a dict inside `with (templates.Defer (dict ...))`
- Don't pipe the page context into Defer — capture what you need in the dict's "data" key instead
When it happens
Trigger: Calling `{{ with (templates.Defer .) }}` or `{{ templates.Defer "key" }}` — passing the page context, a string key, or any other positional value where the function expects none.
Common situations: Assuming Defer takes a data context like `partial` does; trying to pass a cache key directly instead of via the options dict form shown in the docs; copy-paste from an incorrect snippet.
Related errors
- templates.Defer cannot be used inside a partialCached partia
- resources.PostProcess cannot be used in a deferred template
- error building site: %w
- failed to detect format from content
- failed to detect target data serialization format
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/4fa2dcbd99298cc4.json.
Report an issue: GitHub ↗.