go-playground/validator · error

Bad param number for excluded_if %s

Error message

Bad param number for excluded_if %s

What it means

excluded_if excludes the field when all named other fields equal their given values. Its parameters must be field,value pairs; an odd count after parseOneOfParam2 means a dangling field with no value, so the validator panics at baked_in.go:2147.

Source

Thrown at baked_in.go:2147

			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()))
	}

	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()))
	}

View on GitHub (pinned to facf128d2e)

Solutions

  1. Provide complete pairs: `excluded_if=Country,US`.
  2. If you just want exclusion based on another field being present, use excluded_without/excluded_with instead.
  3. Escape/remove commas inside values so the split count stays even.
  4. Test the tag with Validate.Struct in CI.

Example fix

// before
Country string `validate:"excluded_if=IsEU"`

// after
Country string `validate:"excluded_if=IsEU,true"`
Defensive patterns

Strategy: validation

Validate before calling

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

Prevention

When it happens

Trigger: Tag like `excluded_if=Country` or `excluded_if=A,1,B` — odd number of comma-split params. A stray comma inside a value can also produce an odd count.

Common situations: Forgetting the comparison value in the tag; copying param style from excluded_without (plain field list) into excluded_if; generated tags with unescaped commas.

Related errors


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