kataras/iris · error

JetEngine.AddFunc: funcBody argument is not a type of func(J

Error message

JetEngine.AddFunc: funcBody argument is not a type of func(JetArguments) reflect.Value. Got %T instead

What it means

AddFunc only accepts jet.Func or func(JetArguments) reflect.Value. Passing any other Go function signature causes a panic via fmt.Sprintf describing the actual received type.

Source

Thrown at view/jet.go:171

			// if has variadic.

			variadicN := n - 1
			variadicInputs := make([]any, variadicN) // except the first one.

			for i := 0; i < variadicN; i++ {
				variadicInputs[i] = args.Get(i + 1).Interface()
			}

			return reflect.ValueOf(generalFunc(firstInput, variadicInputs...))
		}))

		return
	}

	if jetFunc, ok := funcBody.(jet.Func); !ok {
		alternativeJetFunc, ok := funcBody.(func(JetArguments) reflect.Value)
		if !ok {
			panic(fmt.Sprintf("JetEngine.AddFunc: funcBody argument is not a type of func(JetArguments) reflect.Value. Got %T instead", funcBody))
		}

		s.AddVar(funcName, jet.Func(alternativeJetFunc))
	} else {
		s.AddVar(funcName, jetFunc)
	}
}

// AddVar adds a global variable to the jet template set.
func (s *JetEngine) AddVar(key string, value any) {
	if s.Set != nil {
		s.Set.AddGlobal(key, value)
	} else {
		if s.vars == nil {
			s.vars = make(map[string]any)
		}
		s.vars[key] = value
	}

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Wrap the function: engine.AddFunc("name", jet.Func(func(args jet.JetArguments) reflect.Value { ... }))
  2. Or pass a value of type jet.Func directly
  3. Match the required signature func(JetArguments) reflect.Value exactly

Example fix

// before
engine.AddFunc("greet", func(name string) string { return "hi " + name })
// after
engine.AddFunc("greet", jet.Func(func(args jet.JetArguments) reflect.Value {
    return reflect.ValueOf("hi " + args.Get(0).String())
}))
Defensive patterns

Strategy: type-guard

Validate before calling

func isJetFunc(f any) bool {
    switch f.(type) {
    case jet.Func, func(view.JetArguments) reflect.Value:
        return true
    }
    return false
}

Type guard

func assertJetFunc(f any) (jet.Func, bool) {
    if jf, ok := f.(jet.Func); ok { return jf, true }
    if af, ok := f.(func(view.JetArguments) reflect.Value); ok { return jet.Func(af), true }
    return nil, false
}

Try / catch

defer func() { if r := recover(); r != nil { log.Printf("AddFunc panic: %v", r) } }()
engine.AddFunc(name, fn)

Prevention

When it happens

Trigger: Calling JetEngine.AddFunc(name, f) where f is e.g. func(string) string or func(...interface{}) reflect.Value instead of the two accepted forms.

Common situations: Reusing an ordinary helper function as a template function without wrapping it; migrating code from other template engines whose func signatures differ.

Related errors


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/6004e543ed9d6e0e. Report an issue: GitHub.