gohugoio/hugo · error
value is nil; should be of type %s
Error message
value is nil; should be of type %s
What it means
Returned by prepareArg when the argument value is invalid (reflect zero = nil/absent) but the target parameter type cannot hold nil (not chan/func/interface/map/pointer/slice). This is raised while coercing template arguments to a func/method/Map key type, e.g. calling a func whose param is int but the template passed an unset variable. The %s is the expected type.
Source
Thrown at tpl/internal/go_templates/texttemplate/funcs.go:150
if tmpl != nil && tmpl.common != nil {
tmpl.muFuncs.RLock()
defer tmpl.muFuncs.RUnlock()
if fn := tmpl.execFuncs[name]; fn.IsValid() {
return fn, false, true
}
}
if fn := builtinFuncs()[name]; fn.IsValid() {
return fn, true, true
}
return reflect.Value{}, false, false
}
// prepareArg checks if value can be used as an argument of type argType, and
// converts an invalid value to appropriate zero if possible.
func prepareArg(value reflect.Value, argType reflect.Type) (reflect.Value, error) {
if !value.IsValid() {
if !canBeNil(argType) {
return reflect.Value{}, fmt.Errorf("value is nil; should be of type %s", argType)
}
value = reflect.Zero(argType)
}
if value.Type().AssignableTo(argType) {
return value, nil
}
if intLike(value.Kind()) && intLike(argType.Kind()) && value.Type().ConvertibleTo(argType) {
value = value.Convert(argType)
return value, nil
}
return reflect.Value{}, fmt.Errorf("value has type %s; should be %s", value.Type(), argType)
}
func intLike(typ reflect.Kind) bool {
switch typ {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return true
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:View on GitHub (pinned to 52c9bd7908)
Solutions
- Make the func parameter an interface{} or a nillable type if nil is a valid input.
- Guard in the template with {{if .Field}}...{{end}} before calling the func.
- Provide a non-nil default/zero value for the data before rendering.
- Widen the func signature to accept and explicitly handle nil.
Example fix
// before
// func: func(n int) string
{{ lower .Missing }} // .Missing is nil -> error
// after
// func: func(v any) string
{{ if .Missing }}{{ lower .Missing }}{{ end }} Defensive patterns
Strategy: type-guard
Validate before calling
func safeCallFunc(fn func(int) string, v any) (string, error) {
if v == nil {
return "", fmt.Errorf("argument is nil")
}
n, ok := v.(int)
if !ok {
return "", fmt.Errorf("argument not int: %T", v)
}
return fn(n), nil
} Type guard
func isNonNilAssignable(v any, t reflect.Type) bool {
if v == nil { return false }
rv := reflect.ValueOf(v)
return rv.IsValid() && rv.Type().AssignableTo(t)
} Try / catch
if err := t.Execute(w, data); err != nil {
if strings.Contains(err.Error(), "value is nil; should be of type") {
// provide defaults for nil fields and retry once
data = withDefaults(data)
err = t.Execute(w, data)
}
} Prevention
- Prefer interface{} params in FuncMap funcs when nil is possible.
- Guard template calls with {{if .Field}}...{{end}}.
- Populate non-nil defaults in the data layer.
When it happens
Trigger: Passing nil to a template function/method/index whose parameter type is non-nillable (int, string, struct, array); an unset pipeline variable ($x never assigned) flowing into a typed arg; a missing map key passed to a typed func.
Common situations: Template references a nil context field that feeds a typed func; a partial invoked without expected data; a FuncMap func with a concrete (non-interface) param type receiving a nil dot.
Related errors
- invalid function signature for %s: second return value shoul
- function %s has %d return values; should be 1 or 2
- value has type %s; should be %s
- cannot index slice/array with nil
- cannot index slice/array with type %s
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/d31a869f30ce33d3.
Report an issue: GitHub.