go-playground/validator · error

Bad param number for required_if %s

Error message

Bad param number for required_if %s

What it means

required_if requires an even number of comma-separated parameters: field,value pairs (each 'other field must equal value'). parseOneOfParam2 splits fl.Param(); if the count is odd, a pair is incomplete and the validator panics with 'Bad param number for required_if'.

Source

Thrown at baked_in.go:2123

	case reflect.Ptr:
		if field.IsNil() {
			return value == "nil"
		}
		// Handle non-nil pointers
		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)
}

View on GitHub (pinned to facf128d2e)

Solutions

  1. Supply field,value pairs: change `required_if=OtherField` to `required_if=OtherField,someValue`.
  2. Count params after comma-splitting; escape or remove stray commas inside values.
  3. If you only need 'other field present', use the correct tag (e.g. required_with) instead of required_if.
  4. Add a unit test calling Validate.Struct on the struct so tag syntax errors surface at test time.

Example fix

// before
Active bool
Email string `validate:"required_if=Active"`

// after
Active bool
Email string `validate:"required_if=Active,true"`
Defensive patterns

Strategy: validation

Validate before calling

func checkRequiredIfTag(tagValue string) error {
    parts := strings.Split(tagValue, ",")
    if len(parts)%2 != 0 {
        return fmt.Errorf("required_if 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_if params): %v", r)
        }
    }()
    return v.Struct(s)
}

Prevention

When it happens

Trigger: Tag like `required_if=FieldA` (one param) or `required_if=FieldA,1,FieldB` (three params) — any odd param count after parsing. Note params containing commas are split by parseOneOfParam2, so an unescaped comma inside a value can also shift the count to odd.

Common situations: Hand-written struct tags forgetting the comparison value; dynamically generated tags joining an odd number of tokens; values containing commas not understood by the param parser; typo'd tag copied from required_without (which takes a plain field list).

Related errors


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