{"record":{"id":"b32e07e94298f8b6","repo":"go-playground/validator","slug":"duplicate-param-s-for-required-if-s","errorCode":null,"errorMessage":"Duplicate param %s for required_if %s","messagePattern":"Duplicate param (.+?) for required_if (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baked_in.go","lineNumber":2129,"sourceCode":"\t\treturn requireCheckFieldValue(fl, param, value, defaultNotFoundValue)\n\t}\n\n\t// default reflect.String:\n\treturn field.String() == value\n}\n\n// requiredIf is the validation function\n// 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.\nfunc requiredIf(fl FieldLevel) bool {\n\tparams := parseOneOfParam2(fl.Param())\n\tif len(params)%2 != 0 {\n\t\tpanic(fmt.Sprintf(\"Bad param number for required_if %s\", fl.FieldName()))\n\t}\n\n\tseen := make(map[string]struct{})\n\tfor i := 0; i < len(params); i += 2 {\n\t\tif _, ok := seen[params[i]]; ok {\n\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()))","sourceCodeStart":2111,"sourceCodeEnd":2147,"githubUrl":"https://github.com/go-playground/validator/blob/facf128d2eecf42bd4ff447adc961aa21bb64aed/baked_in.go#L2111-L2147","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before\nStatus string\nEmail  string `validate:\"required_if=Status,A,Status,B\"`\n\n// after\nStatus string\nEmail  string `validate:\"required_if=Status,A\"` // or struct-level validation for multi-value logic","handlingStrategy":"validation","validationCode":"func checkDuplicateParams(tagValue string) error {\n    parts := strings.Split(tagValue, \",\")\n    seen := map[string]bool{}\n    for i := 0; i < len(parts); i += 2 {\n        if seen[parts[i]] {\n            return fmt.Errorf(\"duplicate field %q in tag params %q\", parts[i], tagValue)\n        }\n        seen[parts[i]] = true\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 (duplicate required_if param): %v\", r)\n        }\n    }()\n    return v.Struct(s)\n}","preventionTips":["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"],"tags":["go","validator","panic","struct-tags","required-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"}