gohugoio/hugo · error

non-function %s of type %s

Error message

non-function %s of type %s

What it means

Raised by the `call` action when the value is valid but its Kind is not Func (funcs.go:317-319). `call` only invokes functions/methods; invoking a struct, slice, map, int, etc. is rejected. Format: `name type`.

Source

Thrown at tpl/internal/go_templates/texttemplate/funcs.go:319

	return 0, fmt.Errorf("len of type %s", item.Type())
}

// Function invocation

func emptyCall(fn reflect.Value, args ...reflect.Value) reflect.Value {
	panic("unreachable") // implemented as a special case in evalCall
}

// call returns the result of evaluating the first argument as a function.
// The function must return 1 result, or 2 results, the second of which is an error.
func call(name string, fn reflect.Value, args ...reflect.Value) (reflect.Value, error) {
	fn = indirectInterface(fn)
	if !fn.IsValid() {
		return reflect.Value{}, fmt.Errorf("call of nil")
	}
	typ := fn.Type()
	if typ.Kind() != reflect.Func {
		return reflect.Value{}, fmt.Errorf("non-function %s of type %s", name, typ)
	}

	if err := goodFunc(name, typ); err != nil {
		return reflect.Value{}, err
	}
	numIn := typ.NumIn()
	var dddType reflect.Type
	if typ.IsVariadic() {
		if len(args) < numIn-1 {
			return reflect.Value{}, fmt.Errorf("wrong number of args for %s: got %d want at least %d", name, len(args), numIn-1)
		}
		dddType = typ.In(numIn - 1).Elem()
	} else {
		if len(args) != numIn {
			return reflect.Value{}, fmt.Errorf("wrong number of args for %s: got %d want %d", name, len(args), numIn)
		}
	}
	argv := make([]reflect.Value, len(args))

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Print the type: `{{printf "%T" .X}}`.
  2. Ensure the value is a func registered in FuncMap or a method on the struct.
  3. Use direct method invocation `{{.Method args}}` instead of `call` where possible.

Example fix

// before
{{call .Items 0}}   // .Items is []string

// after
{{index .Items 0}}
Defensive patterns

Strategy: type-guard

Validate before calling

// Verify it's a function before calling:
//   {{printf "%T" .X}}
// Only Kind == Func can be invoked via call.

Type guard

func isFunc(v interface{}) bool {
    return v != nil && reflect.TypeOf(v).Kind() == reflect.Func
}

Prevention

When it happens

Trigger: `{{call .S 5}}` where `.S` is a slice; `{{call .Name}}` on a string; `{{call . 1}}` on a non-function root; shadowing a function name with a data field of a different type.

Common situations: Name collision between a FuncMap entry and a data field; passing a method value incorrectly; refactoring a callback field to a non-callable type.

Related errors


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