{"record":{"id":"5a3e05b27ca6d8d9","repo":"go-playground/validator","slug":"bad-param-number-for-excluded-if-s","errorCode":null,"errorMessage":"Bad param number for excluded_if %s","messagePattern":"Bad param number for excluded_if (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baked_in.go","lineNumber":2147,"sourceCode":"\t\t\tpanic(fmt.Sprintf(\"Duplicate param %s for required_if %s\", params[i], fl.FieldName()))\n\t\t}\n\t\tseen[params[i]] = struct{}{}\n\t}\n\n\tfor i := 0; i < len(params); i += 2 {\n\t\tif !requireCheckFieldValue(fl, params[i], params[i+1], false) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn hasValue(fl)\n}\n\n// excludedIf is the validation function\n// 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.\nfunc excludedIf(fl FieldLevel) bool {\n\tparams := parseOneOfParam2(fl.Param())\n\tif len(params)%2 != 0 {\n\t\tpanic(fmt.Sprintf(\"Bad param number for excluded_if %s\", fl.FieldName()))\n\t}\n\n\tfor i := 0; i < len(params); i += 2 {\n\t\tif !requireCheckFieldValue(fl, params[i], params[i+1], false) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn !hasValue(fl)\n}\n\n// requiredUnless is the validation function\n// 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.\nfunc requiredUnless(fl FieldLevel) bool {\n\tparams := parseOneOfParam2(fl.Param())\n\tif len(params)%2 != 0 {\n\t\tpanic(fmt.Sprintf(\"Bad param number for required_unless %s\", fl.FieldName()))\n\t}\n","sourceCodeStart":2129,"sourceCodeEnd":2165,"githubUrl":"https://github.com/go-playground/validator/blob/facf128d2eecf42bd4ff447adc961aa21bb64aed/baked_in.go#L2129-L2165","documentation":"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.","triggerScenarios":"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.","commonSituations":"Forgetting the comparison value in the tag; copying param style from excluded_without (plain field list) into excluded_if; generated tags with unescaped commas.","solutions":["Provide complete pairs: `excluded_if=Country,US`.","If you just want exclusion based on another field being present, use excluded_without/excluded_with instead.","Escape/remove commas inside values so the split count stays even.","Test the tag with Validate.Struct in CI."],"exampleFix":"// before\nCountry string `validate:\"excluded_if=IsEU\"`\n\n// after\nCountry string `validate:\"excluded_if=IsEU,true\"`","handlingStrategy":"validation","validationCode":"func checkExcludedIfTag(tagValue string) error {\n    parts := strings.Split(tagValue, \",\")\n    if len(parts)%2 != 0 {\n        return fmt.Errorf(\"excluded_if needs field,value pairs; got %d params in %q\", len(parts), tagValue)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"func safeValidate(v *Validate, s interface{}) (err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"validator panic (check excluded_if params): %v\", r)\n        }\n    }()\n    return v.Struct(s)\n}","preventionTips":["Write excluded_if=Field,value with both halves present","Use excluded_without/excluded_with for presence-only exclusion","Lint struct tags in CI","Test conditional tags with both triggering and non-triggering values"],"tags":["go","validator","panic","struct-tags","excluded-if"],"backgroundTag":"invalid-validator-tag-params","analyzedSha":"facf128d2eecf42bd4ff447adc961aa21bb64aed","analyzedAt":"2026-09-02T10:19:04.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}