go-playground/validator · error
Bad param number for required_unless %s
Error message
Bad param number for required_unless %s
What it means
required_unless makes the field required unless every listed field equals its value. Parameters must form complete field,value pairs; an odd count panics at baked_in.go:2163 with 'Bad param number for required_unless'.
Source
Thrown at baked_in.go:2163
params := parseOneOfParam2(fl.Param())
if len(params)%2 != 0 {
panic(fmt.Sprintf("Bad param number for excluded_if %s", fl.FieldName()))
}
for i := 0; i < len(params); i += 2 {
if !requireCheckFieldValue(fl, params[i], params[i+1], false) {
return true
}
}
return !hasValue(fl)
}
// requiredUnless is the validation function
// The field under validation must be present and not empty only unless all the other specified fields are equal to the value following with the specified field.
func requiredUnless(fl FieldLevel) bool {
params := parseOneOfParam2(fl.Param())
if len(params)%2 != 0 {
panic(fmt.Sprintf("Bad param number for required_unless %s", fl.FieldName()))
}
for i := 0; i < len(params); i += 2 {
if requireCheckFieldValue(fl, params[i], params[i+1], false) {
return true
}
}
return hasValue(fl)
}
// skipUnless is the validation function
// The field under validation must be present and not empty only unless all the other specified fields are equal to the value following with the specified field.
func skipUnless(fl FieldLevel) bool {
params := parseOneOfParam2(fl.Param())
if len(params)%2 != 0 {
panic(fmt.Sprintf("Bad param number for skip_unless %s", fl.FieldName()))
}
for i := 0; i < len(params); i += 2 {View on GitHub (pinned to facf128d2e)
Solutions
- Write full pairs: `required_unless=Role,admin`.
- Verify the param splits into an even number after comma parsing.
- Use required_without if you only need field-presence semantics.
- Cover the tag with a unit test.
Example fix
// before Role string SSN string `validate:"required_unless=Role"` // after Role string SSN string `validate:"required_unless=Role,admin"`
Defensive patterns
Strategy: validation
Validate before calling
func checkRequiredUnlessTag(tagValue string) error {
parts := strings.Split(tagValue, ",")
if len(parts)%2 != 0 {
return fmt.Errorf("required_unless needs field,value pairs; got %d params in %q", len(parts), tagValue)
}
return nil
} Try / catch
func safeValidate(v *Validate, s interface{}) (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("validator panic (check required_unless params): %v", r)
}
}()
return v.Struct(s)
} Prevention
- Write required_unless=Field,value pairs, not bare field lists
- Don't confuse with required_without (which takes bare field names)
- Escape commas inside values
- Add tag smoke tests to CI
When it happens
Trigger: Tag like `required_unless=Role` or `required_unless=Role,admin,Level` — odd comma-split param count, often from a missing value or an unescaped comma in a value.
Common situations: Tag copied from required_unless docs of another library that takes bare field names; missing value after a field name; dynamic tag builders appending an odd token.
Related errors
- Bad param number for required_if %s
- Duplicate param %s for required_if %s
- Bad param number for excluded_if %s
- Bad param number for skip_unless %s
- Bad param number for excluded_unless %s
AI-assisted analysis of go-playground/validator@facf128d2e (2026-09-02).
Data as JSON: /api/errors/5d6f75d8123603b5.
Report an issue: GitHub.