{"record":{"id":"53b37ada418f8999","repo":"go-playground/validator","slug":"tag-s-either-contains-restricted-characters-or","errorCode":null,"errorMessage":"Tag '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation","messagePattern":"Tag '(.+?)' either contains restricted characters or is the same as a restricted tag needed for normal operation","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"validator_instance.go","lineNumber":754,"sourceCode":"\t\terr = vd.errs\n\t\tvd.errs = nil\n\t}\n\tv.pool.Put(vd)\n\treturn\n}\n\nfunc (v *Validate) registerValidation(tag string, fn FuncCtx, bakedIn bool, nilCheckable bool) error {\n\tif len(tag) == 0 {\n\t\treturn errors.New(\"function Key cannot be empty\")\n\t}\n\n\tif fn == nil {\n\t\treturn errors.New(\"function cannot be empty\")\n\t}\n\n\t_, ok := restrictedTags[tag]\n\tif !bakedIn && (ok || strings.ContainsAny(tag, restrictedTagChars)) {\n\t\tpanic(fmt.Sprintf(restrictedTagErr, tag))\n\t}\n\tv.validations[tag] = internalValidationFuncWrapper{fn: fn, runValidationOnNil: nilCheckable}\n\treturn nil\n}\n","sourceCodeStart":736,"sourceCodeEnd":759,"githubUrl":"https://github.com/go-playground/validator/blob/facf128d2eecf42bd4ff447adc961aa21bb64aed/validator_instance.go#L736-L759","documentation":"validator_instance.go:754 panics in registerValidation when a non-baked-in custom tag name is already in restrictedTags or contains restrictedTagChars ('-', '=', etc.). Just like RegisterAlias, custom validator names must not collide with built-in tags or contain tag-grammar characters, because that would corrupt tag parsing. Note the same function returns an error (not a panic) when fn is nil — the panic is specific to the tag name.","triggerScenarios":"v.RegisterValidation(\"required\", myFunc) — re-registering a restricted built-in name; v.RegisterValidation(\"my-func\", fn) with a dash or other restrictedTagChars in the name; wrapping RegisterValidation with dynamically built tag names that include restricted characters; attempting to override email/uuid with custom logic.","commonSituations":"Teams trying to override baked-in validators (upgrade path from older validator versions that allowed it); naming custom validators with kebab-case; user-supplied or config-driven tag names passed straight to RegisterValidation; copy-pasted registration code where someone renamed the tag adding separators.","solutions":["Choose a custom tag name that is not in the restrictedTags denylist and contains only safe characters (letters, digits, underscore).","If you need different behavior than a baked-in tag, register it under a new name and use that name in your struct tags.","Sanitize/validate dynamic tag names before calling RegisterValidation (reject names containing '-', '=', '.', ',', '|').","For nil-function mistakes, check fn != nil before registering — that path returns an error rather than panicking but is easy to conflate.","Register all custom validators in package init at startup so panics are caught at boot."],"exampleFix":"// before\nv.RegisterValidation(\"my-validator\", myFunc)  // '-' restricted\nv.RegisterValidation(\"email\", overrideEmail) // restricted tag\n\n// after\nv.RegisterValidation(\"myValidator\", myFunc)\nv.RegisterValidation(\"customEmail\", overrideEmail)","handlingStrategy":"validation","validationCode":"func safeRegisterValidation(v *validator.Validate, tag string, fn validator.FuncCtx) (err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"invalid tag %q: %v\", tag, r)\n        }\n    }()\n    return v.RegisterValidationCtx(tag, fn)\n}","typeGuard":"var validTagRe = regexp.MustCompile(`^[A-Za-z_][A-Za-z0-9_]*$`)\n\nfunc isSafeCustomTag(tag string) bool {\n    return validTagRe.MatchString(tag)\n}","tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        err = fmt.Errorf(\"RegisterValidation rejected %q: %v\", tag, r)\n    }\n}()\nerr = v.RegisterValidation(tag, fn)","preventionTips":["Use letters, digits, underscore for custom tag names; reject names containing '-', '=', '.', ',', '|'.","Never register a name that matches a baked-in tag; check restrictedTags first.","Sanitize user/config-supplied tag names before registration.","Register all custom validators at startup and add a boot-time test."],"tags":["go","validator","custom-validation","panic","restricted-tags"],"backgroundTag":"restricted-tag-name","analyzedSha":"facf128d2eecf42bd4ff447adc961aa21bb64aed","analyzedAt":"2026-09-02T10:19:04.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}