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

  1. Deduplicate field names in the tag; keep one field,value pair per field.
  2. 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.
  3. If tags are generated, dedupe condition keys before joining with commas.
  4. 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

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


AI-assisted analysis of go-playground/validator@facf128d2e (2026-09-02). Data as JSON: /api/errors/b32e07e94298f8b6. Report an issue: GitHub.