gohugoio/hugo · error
%v
Error message
%v
What it means
Raised by `safeCall` when the invoked function panics (funcs.go:356-364). The panic value is recovered and returned as a template-execution error formatted with `%v`. This surfaces arbitrary panics from user-supplied FuncMap entries or builtins as template errors rather than crashing the process.
Source
Thrown at tpl/internal/go_templates/texttemplate/funcs.go:362
}
var err error
if argv[i], err = prepareArg(arg, argType); err != nil {
return reflect.Value{}, fmt.Errorf("arg %d: %w", i, err)
}
}
return safeCall(fn, argv)
}
// safeCall runs fun.Call(args), and returns the resulting value and error, if
// any. If the call panics, the panic value is returned as an error.
func safeCall(fun reflect.Value, args []reflect.Value) (val reflect.Value, err error) {
defer func() {
if r := recover(); r != nil {
if e, ok := r.(error); ok {
err = e
} else {
err = fmt.Errorf("%v", r)
}
}
}()
ret := fun.Call(args)
if len(ret) == 2 && !ret[1].IsNil() {
return ret[0], ret[1].Interface().(error)
}
return ret[0], nil
}
// Boolean logic.
func truth(arg reflect.Value) bool {
t, _ := isTrue(indirectInterface(arg))
return t
}
// and computes the Boolean AND of its arguments, returningView on GitHub (pinned to 52c9bd7908)
Solutions
- Reproduce the call in Go and fix the panic at its source (the function body).
- Add nil/error checks in the func and return a proper `error` (the (value, error) return convention) instead of panicking.
- Validate inputs in the template before calling.
- Pin or upgrade the module exposing the panicking function.
Example fix
// before (Go func)
func first(s []string) string { return s[0] } // panics on empty
// after
func first(s []string) (string, error) {
if len(s) == 0 { return "", errors.New("empty slice") }
return s[0], nil
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate inputs in-template before calling:
// {{if .S}}{{call .First .S}}{{end}}
// Better: fix the func to return (value, error) and check inputs. Try / catch
// safeCall already recovers panics into errors; surface them:
// In Go rendering code:
err := tmpl.Execute(w, data)
if err != nil {
var pe *template.Error
if errors.As(err, &pe) {
log.Printf("template exec error: %v", pe)
}
return err
} Prevention
- Make custom FuncMap entries return (value, error) and never panic.
- Add nil/bounds checks inside funcs called from templates.
- Reproduce panicking funcs in isolation under tests.
When it happens
Trigger: A registered FuncMap entry that panics (nil deref, index-out-of-range, divide-by-zero, explicit `panic()`); a method called via template that performs an unsafe operation on its inputs.
Common situations: Buggy custom template functions; funcs that assume non-nil input but receive nil from templates; integer division by zero in a helper; third-party Hugo module exposing a panicking func.
Related errors
- call of nil
- non-function %s of type %s
- wrong number of args for %s: got %d want at least %d
- wrong number of args for %s: got %d want %d
- arg %d: %w
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/12d739bd02026e9d.
Report an issue: GitHub.