beego/beego · warning

invalid function name: %s

Error message

invalid function name: %s

What it means

AddCustomFunc (core/validation/util.go:82) rejects names that collide with the Validation type's own methods — the reserved set Clear, HasErrors, ErrorMap, Error, apply, Check, Valid, NoMatch — because a colliding entry would shadow or break method-derived dispatch. Any of those exact names yields this error and the function is not registered.

Source

Thrown at core/validation/util.go:82

// CustomFunc is for custom validate function
type CustomFunc func(v *Validation, obj interface{}, key string)

// AddCustomFunc Add a custom function to validation
// The name can not be:
//
//	Clear
//	HasErrors
//	ErrorMap
//	Error
//	Check
//	Valid
//	NoMatch
//
// If the name is same with exists function, it will replace the origin valid function
func AddCustomFunc(name string, f CustomFunc) error {
	if unFuncs[name] {
		return fmt.Errorf("invalid function name: %s", name)
	}

	funcs[name] = reflect.ValueOf(f)
	return nil
}

// ValidFunc Valid function type
type ValidFunc struct {
	Name   string
	Params []interface{}
}

// Funcs Validate function map
type Funcs map[string]reflect.Value

// Call validate values with named type string
func (f Funcs) Call(name string, params ...interface{}) (result []reflect.Value, err error) {
	defer func() {

View on GitHub (pinned to 939cfde380)

Solutions

  1. Pick a distinct name that still reads like a rule (CheckPhone, ValidSKU, ErrorState)
  2. Assert on AddCustomFunc's error so bad names fail in tests, not silently at runtime
  3. Keep a project-level list of registered rule names and lint tags against it

Example fix

// before
err := validation.AddCustomFunc("Check", func(...) *validation.Result { ... }) // invalid function name: Check

// after
err := validation.AddCustomFunc("CheckPhone", func(...) *validation.Result { ... })
Defensive patterns

Strategy: validation

Validate before calling

var reservedRuleNames = map[string]bool{
    "Clear": true, "HasErrors": true, "ErrorMap": true, "Error": true,
    "apply": true, "Check": true, "Valid": true, "NoMatch": true,
}
if reservedRuleNames[name] {
    return fmt.Errorf("rule name %q is reserved by Validation", name)
}
err := validation.AddCustomFunc(name, fn)

Try / catch

if err := validation.AddCustomFunc(name, fn); err != nil {
    if strings.Contains(err.Error(), "invalid function name") {
        name = "X" + name // deterministic de-conflict prefix, then retry once
        err = validation.AddCustomFunc(name, fn)
    }
    if err != nil {
        return err
    }
}

Prevention

When it happens

Trigger: validation.AddCustomFunc("Check", myFunc), "Valid", "Error", "Clear", "HasErrors", "ErrorMap", "apply", or "NoMatch"; copying sample custom validators that happen to use these names.

Common situations: Migrating custom validators from another framework where Check/Valid were conventional names; naming a rule 'Error' for error-code checks.

Related errors


AI-assisted analysis of beego/beego@939cfde380 (2026-08-15). Data as JSON: /api/errors/d4a7b0fa68c7e08f. Report an issue: GitHub.