go-playground/validator · error
Bad param number for skip_unless %s
Error message
Bad param number for skip_unless %s
What it means
skip_unless skips requiring the field unless all listed field,value conditions fail... its params must be field,value pairs; an odd count after parseOneOfParam2 panics at baked_in.go:2179 with 'Bad param number for skip_unless'.
Source
Thrown at baked_in.go:2179
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 {
if !requireCheckFieldValue(fl, params[i], params[i+1], false) {
return true
}
}
return hasValue(fl)
}
// excludedUnless is the validation function
// The field under validation must not be present or is empty unless all the other specified fields are equal to the value following with the specified field.
func excludedUnless(fl FieldLevel) bool {
params := parseOneOfParam2(fl.Param())
if len(params)%2 != 0 {
panic(fmt.Sprintf("Bad param number for excluded_unless %s", fl.FieldName()))
}
for i := 0; i < len(params); i += 2 {
if requireCheckFieldValue(fl, params[i], params[i+1], false) {View on GitHub (pinned to facf128d2e)
Solutions
- Supply pairs: `skip_unless=Mode,advanced`.
- Check for stray commas in values; escape or restructure.
- Confirm the intended tag family (skip_unless vs required_unless/excluded_unless all share the pair rule).
- Add a regression test for the tag string.
Example fix
// before Mode string Note string `validate:"skip_unless=Mode"` // after Mode string Note string `validate:"skip_unless=Mode,basic"`
Defensive patterns
Strategy: validation
Validate before calling
func checkSkipUnlessTag(tagValue string) error {
parts := strings.Split(tagValue, ",")
if len(parts)%2 != 0 {
return fmt.Errorf("skip_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 skip_unless params): %v", r)
}
}()
return v.Struct(s)
} Prevention
- Provide complete field,value pairs for skip_unless
- Keep the same pair convention across all *_if/*_unless conditional tags
- Escape commas in values
- Unit-test the tag string against Validate.Struct
When it happens
Trigger: Tag like `skip_unless=Mode` or `skip_unless=A,1,B` — incomplete field,value pair (odd param count), including cases where a value containing a comma distorts the split.
Common situations: Missing comparison value in a hand-written tag; mixing up parameter conventions with skip_use/skip_without style tags; programmatic tag generation bugs.
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 required_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/85036d38a3fbd2b5.
Report an issue: GitHub.