{"record":{"id":"b65f08e476878995","repo":"go-playground/validator","slug":"bad-param-number-for-excluded-unless-s","errorCode":null,"errorMessage":"Bad param number for excluded_unless %s","messagePattern":"Bad param number for excluded_unless (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baked_in.go","lineNumber":2194,"sourceCode":"func skipUnless(fl FieldLevel) bool {\n\tparams := parseOneOfParam2(fl.Param())\n\tif len(params)%2 != 0 {\n\t\tpanic(fmt.Sprintf(\"Bad param number for skip_unless %s\", fl.FieldName()))\n\t}\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// excludedUnless is the validation function\n// The field under validation must not be present or is empty unless all the other specified fields are equal to the value following with the specified field.\nfunc excludedUnless(fl FieldLevel) bool {\n\tparams := parseOneOfParam2(fl.Param())\n\tif len(params)%2 != 0 {\n\t\tpanic(fmt.Sprintf(\"Bad param number for excluded_unless %s\", fl.FieldName()))\n\t}\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\n\treturn !hasValue(fl)\n}\n\n// excludedWith is the validation function\n// The field under validation must not be present or is empty if any of the other specified fields are present.\nfunc excludedWith(fl FieldLevel) bool {\n\tparams := parseOneOfParam2(fl.Param())\n\tfor _, param := range params {\n\t\tif !requireCheckFieldKind(fl, param, true) {\n\t\t\treturn !hasValue(fl)\n\t\t}","sourceCodeStart":2176,"sourceCodeEnd":2212,"githubUrl":"https://github.com/go-playground/validator/blob/facf128d2eecf42bd4ff447adc961aa21bb64aed/baked_in.go#L2176-L2212","documentation":"excluded_unless excludes the field unless all listed fields equal their values. Like the other *_if/*_unless conditionals, its params must be complete field,value pairs; an odd count panics at baked_in.go:2194.","triggerScenarios":"Tag like `excluded_unless=Status` or `excluded_unless=A,1,B` — dangling field name without a value, or an unescaped comma making the count odd.","commonSituations":"Forgetting the value half of a pair; copying syntax from excluded_without (bare field list); generated tags with malformed joins.","solutions":["Provide field,value pairs: `excluded_unless=Status,archived`.","Validate the comma-split count is even.","Switch to excluded_without for presence-only semantics.","Unit-test the struct tag."],"exampleFix":"// before\nStatus  string\nDeleted string `validate:\"excluded_unless=Status\"`\n\n// after\nStatus  string\nDeleted string `validate:\"excluded_unless=Status,active\"`","handlingStrategy":"validation","validationCode":"func checkExcludedUnlessTag(tagValue string) error {\n    parts := strings.Split(tagValue, \",\")\n    if len(parts)%2 != 0 {\n        return fmt.Errorf(\"excluded_unless 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_unless params): %v\", r)\n        }\n    }()\n    return v.Struct(s)\n}","preventionTips":["Write excluded_unless=Field,value with both halves","Use excluded_without for bare field-name semantics","Check generated tag builders emit even token counts","Add CI tests exercising every conditional tag"],"tags":["go","validator","panic","struct-tags","excluded-unless"],"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"}