go-playground/validator · critical
Invalid validation tag on field '%s'
Error message
Invalid validation tag on field '%s'
What it means
A tag segment parsed to an empty validator name (e.g. a leading/trailing comma or `,|,` leaving an empty tag before params). cache.go panics with "Invalid validation tag on field '<FieldName>'" when building the tag cache for the struct.
Source
Thrown at cache.go:286
for j := 0; j < len(orVals); j++ {
vals := strings.SplitN(orVals[j], tagKeySeparator, 2)
if noAlias {
alias = vals[0]
current.aliasTag = alias
} else {
current.actualAliasTag = t
}
if j > 0 {
current.next = &cTag{aliasTag: alias, actualAliasTag: current.actualAliasTag, hasAlias: hasAlias, hasTag: true}
current = current.next
}
current.hasParam = len(vals) > 1
current.tag = vals[0]
if len(current.tag) == 0 {
panic(strings.TrimSpace(fmt.Sprintf(invalidValidation, fieldName)))
}
if wrapper, ok := v.validations[current.tag]; ok {
current.fn = wrapper.fn
current.runValidationWhenNil = wrapper.runValidationOnNil
} else if aliasTag, isAlias := v.aliases[current.tag]; isAlias {
aliasFirst, aliasLast := v.parseFieldTagsRecursive(aliasTag, fieldName, current.tag, true)
current.tag = aliasFirst.tag
current.fn = aliasFirst.fn
current.runValidationWhenNil = aliasFirst.runValidationWhenNil
current.hasParam = aliasFirst.hasParam
current.param = aliasFirst.param
current.typeof = aliasFirst.typeof
current.hasAlias = true
if aliasFirst.next != nil {
nextInChain := current.nextView on GitHub (pinned to facf128d2e)
Solutions
- Remove empty tag entries / duplicate commas from the struct tag
- Fix the code that generates the tag string so it never emits an empty segment
- Check aliases: an alias expanding to an empty string produces this panic
- Add a startup test validating a representative struct instance to fail fast
Example fix
// before Name string `validate:",required"` // after Name string `validate:"required"`
Defensive patterns
Strategy: validation
Validate before calling
func checkEmptyTags(t reflect.StructTag) error {
for i, tg := range strings.Split(t.Get("validate"), ",") {
if strings.TrimSpace(tg) == "" {
return fmt.Errorf("empty tag segment at index %d", i)
}
}
return nil
} Try / catch
func validateStrict(s any) (err error) {
defer func() {
if r := recover(); r != nil {
if strings.Contains(fmt.Sprint(r), "Invalid validation tag") {
err = fmt.Errorf("malformed struct tag: %v", r)
} else { panic(r) }
}
}()
return validate.Struct(s)
} Prevention
- Never build validate tags with Sprintf on possibly-empty variables
- Strip empty segments when generating tags programmatically
- Check aliases for empty expansions
- Fail fast with an init-time validation of every struct type
When it happens
Trigger: Struct tag containing empty tag entries such as `validate:",required"`, `validate:"required,,min=1"`, or an alias expanding to an empty tag; malformed tags from code-generated structs.
Common situations: String-built tags where variables are empty (fmt.Sprintf("validate:%s,%s", emptyVar, "required")); trailing commas after refactors; ORM/struct generators emitting extra commas.
Related errors
- '%s' tag must be immediately preceded by the '%s' tag
- 'endkeys' tag encountered without a corresponding 'keys' tag
- Bad field type %T
- panic(err) (os.Stat *PathError re-raised for unexpected stat
- Bad param number for required_if %s
AI-assisted analysis of go-playground/validator@facf128d2e (2026-09-02).
Data as JSON: /api/errors/f3e40bf5a2e90606.
Report an issue: GitHub.