{"record":{"id":"d4a7b0fa68c7e08f","repo":"beego/beego","slug":"invalid-function-name-s","errorCode":null,"errorMessage":"invalid function name: %s","messagePattern":"invalid function name: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/validation/util.go","lineNumber":82,"sourceCode":"\n// CustomFunc is for custom validate function\ntype CustomFunc func(v *Validation, obj interface{}, key string)\n\n// AddCustomFunc Add a custom function to validation\n// The name can not be:\n//\n//\tClear\n//\tHasErrors\n//\tErrorMap\n//\tError\n//\tCheck\n//\tValid\n//\tNoMatch\n//\n// If the name is same with exists function, it will replace the origin valid function\nfunc AddCustomFunc(name string, f CustomFunc) error {\n\tif unFuncs[name] {\n\t\treturn fmt.Errorf(\"invalid function name: %s\", name)\n\t}\n\n\tfuncs[name] = reflect.ValueOf(f)\n\treturn nil\n}\n\n// ValidFunc Valid function type\ntype ValidFunc struct {\n\tName   string\n\tParams []interface{}\n}\n\n// Funcs Validate function map\ntype Funcs map[string]reflect.Value\n\n// Call validate values with named type string\nfunc (f Funcs) Call(name string, params ...interface{}) (result []reflect.Value, err error) {\n\tdefer func() {","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/beego/beego/blob/939cfde380bb9f15844ad633b84f037f7da21584/core/validation/util.go#L64-L100","documentation":"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.","triggerScenarios":"validation.AddCustomFunc(\"Check\", myFunc), \"Valid\", \"Error\", \"Clear\", \"HasErrors\", \"ErrorMap\", \"apply\", or \"NoMatch\"; copying sample custom validators that happen to use these names.","commonSituations":"Migrating custom validators from another framework where Check/Valid were conventional names; naming a rule 'Error' for error-code checks.","solutions":["Pick a distinct name that still reads like a rule (CheckPhone, ValidSKU, ErrorState)","Assert on AddCustomFunc's error so bad names fail in tests, not silently at runtime","Keep a project-level list of registered rule names and lint tags against it"],"exampleFix":"// before\nerr := validation.AddCustomFunc(\"Check\", func(...) *validation.Result { ... }) // invalid function name: Check\n\n// after\nerr := validation.AddCustomFunc(\"CheckPhone\", func(...) *validation.Result { ... })","handlingStrategy":"validation","validationCode":"var reservedRuleNames = map[string]bool{\n    \"Clear\": true, \"HasErrors\": true, \"ErrorMap\": true, \"Error\": true,\n    \"apply\": true, \"Check\": true, \"Valid\": true, \"NoMatch\": true,\n}\nif reservedRuleNames[name] {\n    return fmt.Errorf(\"rule name %q is reserved by Validation\", name)\n}\nerr := validation.AddCustomFunc(name, fn)","typeGuard":null,"tryCatchPattern":"if err := validation.AddCustomFunc(name, fn); err != nil {\n    if strings.Contains(err.Error(), \"invalid function name\") {\n        name = \"X\" + name // deterministic de-conflict prefix, then retry once\n        err = validation.AddCustomFunc(name, fn)\n    }\n    if err != nil {\n        return err\n    }\n}","preventionTips":["Never name a rule after a Validation method — prefix custom rules (MyCheck)","Check AddCustomFunc's error in a unit test for every rule you register","Keep the reserved list above in your code-review checklist for tag names"],"tags":["validation","custom-func","reserved-name","registration"],"backgroundTag":null,"analyzedSha":"939cfde380bb9f15844ad633b84f037f7da21584","analyzedAt":"2026-08-15T17:22:06.535Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}