{"id":"2e038f03d1409a41","repo":"go-redis/redis","slug":"redis-filter-by-value-requires-exactly-2-elements","errorCode":null,"errorMessage":"redis: FILTER_BY_VALUE requires exactly 2 elements [min, max], got %d","messagePattern":"redis: FILTER_BY_VALUE requires exactly 2 elements \\[min, max\\], got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"timeseries_commands.go","lineNumber":1425,"sourceCode":"\tcount int,\n\talign interface{},\n\taggregators [][]Aggregator,\n\tbucketDuration int,\n\tbucketTimestamp interface{},\n\tempty bool,\n) ([]interface{}, error) {\n\tif latest {\n\t\targs = append(args, \"LATEST\")\n\t}\n\tif len(filterByTS) > 0 {\n\t\targs = append(args, \"FILTER_BY_TS\")\n\t\tfor _, ts := range filterByTS {\n\t\t\targs = append(args, ts)\n\t\t}\n\t}\n\tif len(filterByValue) > 0 {\n\t\tif len(filterByValue) != 2 {\n\t\t\treturn args, fmt.Errorf(\"redis: FILTER_BY_VALUE requires exactly 2 elements [min, max], got %d\", len(filterByValue))\n\t\t}\n\t\targs = append(args, \"FILTER_BY_VALUE\", filterByValue[0], filterByValue[1])\n\t}\n\tif count != 0 {\n\t\targs = append(args, \"COUNT\", count)\n\t}\n\tif align != nil {\n\t\targs = append(args, \"ALIGN\", align)\n\t}\n\tif len(aggregators) > 0 {\n\t\taggParts, err := buildNRangeAggregationArgs(keys, aggregators)\n\t\tif err != nil {\n\t\t\treturn args, err\n\t\t}\n\t\targs = append(args, \"AGGREGATION\")\n\t\tfor _, a := range aggParts {\n\t\t\targs = append(args, a)\n\t\t}","sourceCodeStart":1407,"sourceCodeEnd":1443,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/timeseries_commands.go#L1407-L1443","documentation":"Returned by appendNRangeOptions when the FilterByValue option is non-empty but does not have exactly two elements. TS.NRANGE/TS.NREVRANGE FILTER_BY_VALUE semantics require a [min, max] pair, so any other length is rejected.","triggerScenarios":"Calling TSNRangeWithArgs/TSNRevRangeWithArgs with options.FilterByValue of length 1 or >=3 (length 0 is allowed and means 'no filter').","commonSituations":"Passing a single threshold intending min-only filtering, appending min and max separately and missing one, or reusing a slice that holds more than two values.","solutions":["Pass exactly two values [min, max] in options.FilterByValue.","Leave FilterByValue empty/nil to disable value filtering.","Assert len(FilterByValue) == 0 || len(FilterByValue) == 2 before the call."],"exampleFix":"// before\nopts := &redis.TSNRangeOptions{FilterByValue: []float64{1.5}}\nclient.TSNRangeWithArgs(ctx, keys, 0, -1, opts)\n\n// after\nopts := &redis.TSNRangeOptions{FilterByValue: []float64{1.5, 9.5}}\nclient.TSNRangeWithArgs(ctx, keys, 0, -1, opts)","handlingStrategy":"validation","validationCode":"func validateFilterByValue(v []float64) error {\n    if len(v) != 0 && len(v) != 2 {\n        return fmt.Errorf(\"FilterByValue must have 2 elements [min,max], got %d\", len(v))\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass FilterByValue as a literal [2]float64 or a two-element slice.","Leave FilterByValue nil to disable value filtering.","Assert the length is 0 or 2 in a shared validator for all TS range options."],"tags":["timeseries","nrange","filter","validation","count-mismatch"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}