go-playground/validator · error
Duplicate param %s for required_if %s
Error message
Duplicate param %s for required_if %s
What it means
required_if panics when the same field name appears more than once in its parameter list. Duplicate pairs are ambiguous/pointless, so the guard at baked_in.go:2129 rejects them with 'Duplicate param ... for required_if'.
Source
Thrown at baked_in.go:2129
return requireCheckFieldValue(fl, param, value, defaultNotFoundValue)
}
// default reflect.String:
return field.String() == value
}
// requiredIf is the validation function
// The field under validation must be present and not empty only if all the other specified fields are equal to the value following with the specified field.
func requiredIf(fl FieldLevel) bool {
params := parseOneOfParam2(fl.Param())
if len(params)%2 != 0 {
panic(fmt.Sprintf("Bad param number for required_if %s", fl.FieldName()))
}
seen := make(map[string]struct{})
for i := 0; i < len(params); i += 2 {
if _, ok := seen[params[i]]; ok {
panic(fmt.Sprintf("Duplicate param %s for required_if %s", params[i], fl.FieldName()))
}
seen[params[i]] = struct{}{}
}
for i := 0; i < len(params); i += 2 {
if !requireCheckFieldValue(fl, params[i], params[i+1], false) {
return true
}
}
return hasValue(fl)
}
// excludedIf is the validation function
// The field under validation must not be present or is empty only if all the other specified fields are equal to the value following with the specified field.
func excludedIf(fl FieldLevel) bool {
params := parseOneOfParam2(fl.Param())
if len(params)%2 != 0 {
panic(fmt.Sprintf("Bad param number for excluded_if %s", fl.FieldName()))View on GitHub (pinned to facf128d2e)
Solutions
- Deduplicate field names in the tag; keep one field,value pair per field.
- Need multiple values to trigger required? required_if only supports equality per pair — use a custom validator or struct-level validation for OR-of-values logic.
- If tags are generated, dedupe condition keys before joining with commas.
- Add tests covering the exact tag string.
Example fix
// before Status string Email string `validate:"required_if=Status,A,Status,B"` // after Status string Email string `validate:"required_if=Status,A"` // or struct-level validation for multi-value logic
Defensive patterns
Strategy: validation
Validate before calling
func checkDuplicateParams(tagValue string) error {
parts := strings.Split(tagValue, ",")
seen := map[string]bool{}
for i := 0; i < len(parts); i += 2 {
if seen[parts[i]] {
return fmt.Errorf("duplicate field %q in tag params %q", parts[i], tagValue)
}
seen[parts[i]] = true
}
return nil
} Try / catch
func safeValidate(v *Validate, s interface{}) (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("validator panic (duplicate required_if param): %v", r)
}
}()
return v.Struct(s)
} Prevention
- Keep one field,value pair per field name in required_if
- Deduplicate condition keys when generating tags programmatically
- For multi-value triggers use struct-level validation instead of repeated pairs
- Review hand-edited tags during code review
When it happens
Trigger: Tag like `required_if=Status,A,Status,B` or `required_if=Type,X,Type,X` — the same left-hand field repeated across pairs. Also occurs when generated tags concatenate conditions that reuse a field.
Common situations: Building tag strings programmatically from a conditions map/list without deduplication; hand-editing a tag to add a second value for the same field instead of using a different tag (e.g. required_if + oneof semantics).
Related errors
- Bad param number for required_if %s
- Bad param number for excluded_if %s
- Bad param number for required_unless %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/b32e07e94298f8b6.
Report an issue: GitHub.