{"record":{"id":"af394ff900b8247c","repo":"redis/go-redis","slug":"ft-aggregate-steps-cannot-be-combined-with-the-de","errorCode":null,"errorMessage":"FT.AGGREGATE: Steps cannot be combined with the deprecated Load, Apply, GroupBy, SortBy and SortByMax fields","messagePattern":"FT\\.AGGREGATE: Steps cannot be combined with the deprecated Load, Apply, GroupBy, SortBy and SortByMax fields","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"search_commands.go","lineNumber":691,"sourceCode":"\n// FTAggregate - Performs a search query on an index and applies a series of aggregate transformations to the result.\n// The 'index' parameter specifies the index to search, and the 'query' parameter specifies the search query.\n// For more information, please refer to the Redis documentation:\n// [FT.AGGREGATE]: (https://redis.io/commands/ft.aggregate/)\nfunc (c cmdable) FTAggregate(ctx context.Context, index string, query string) *MapStringInterfaceCmd {\n\targs := []interface{}{\"FT.AGGREGATE\", index, query}\n\tcmd := NewMapStringInterfaceCmd(ctx, args...)\n\t_ = c(ctx, cmd)\n\treturn cmd\n}\n\n// validateFTAggregateOptions validates mutually exclusive combinations of\n// FTAggregateOptions fields before any command arguments are constructed.\nfunc validateFTAggregateOptions(options *FTAggregateOptions) error {\n\tif len(options.Steps) > 0 {\n\t\tif options.Load != nil || options.Apply != nil || options.GroupBy != nil ||\n\t\t\toptions.SortBy != nil || options.SortByMax != 0 {\n\t\t\treturn fmt.Errorf(\"FT.AGGREGATE: Steps cannot be combined with the deprecated Load, Apply, GroupBy, SortBy and SortByMax fields\")\n\t\t}\n\t\tif options.LoadAll {\n\t\t\tfor _, step := range options.Steps {\n\t\t\t\tif step.Load != nil {\n\t\t\t\t\treturn fmt.Errorf(\"FT.AGGREGATE: LOADALL and LOAD are mutually exclusive\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif options.LoadAll && options.Load != nil {\n\t\treturn fmt.Errorf(\"FT.AGGREGATE: LOADALL and LOAD are mutually exclusive\")\n\t}\n\treturn nil\n}\n\n// appendFTAggregateStep appends the Redis command arguments for a single\n// aggregation pipeline step. Each step must set exactly one of Load, Apply,\n// GroupBy or SortBy.","sourceCodeStart":673,"sourceCodeEnd":709,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/search_commands.go#L673-L709","documentation":"FTAggregateOptions supports two generations of API: the deprecated flat fields (Load, Apply, GroupBy, SortBy, SortByMax) and the newer Steps list. They are mutually exclusive — mixing them would produce ambiguous or duplicated pipeline clauses, so validateFTAggregateOptions rejects the combination before any args are built.","triggerScenarios":"Passing an FTAggregateOptions with both len(Steps) > 0 and any of Load != nil, Apply != nil, GroupBy != nil, SortBy != nil, or SortByMax != 0 to FTAggregateWithArgs.","commonSituations":"Migrating old code to Steps while leaving deprecated fields populated; merging two option structs built by different code paths; copy-paste adding Steps on top of legacy options.","solutions":["Move all deprecated fields into equivalent Steps (QueryStep, LoadStep, ApplyStep, GroupByStep, SortByStep) and zero out the old fields","Zero the deprecated fields when constructing Steps (Load: nil, SortByMax: 0, etc.)","Audit option-construction helpers so only one style is produced"],"exampleFix":"// before\nopts := &redis.FTAggregateOptions{\n\tSortBy: &redis.FTAggregateSortBy{FieldName: \"@d\"},\n\tSteps: []redis.FTAggregateStep{{Step: \"GROUPBY\", ...}},\n}\n// after\nopts := &redis.FTAggregateOptions{\n\tSteps: []redis.FTAggregateStep{\n\t\t{Step: \"SORTBY\", SortBy: ...},\n\t\t{Step: \"GROUPBY\", ...},\n\t},\n}","handlingStrategy":"validation","validationCode":"if len(opts.Steps) > 0 && (opts.Load != nil || opts.Apply != nil || opts.GroupBy != nil || opts.SortBy != nil || opts.SortByMax != 0) {\n    return fmt.Errorf(\"Steps cannot be combined with deprecated FTAggregateOptions fields\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When migrating to Steps, explicitly zero the deprecated fields","Produce options through a single helper that uses only one style","Add a test asserting deprecated fields are nil when Steps are set"],"tags":["search","ft-aggregate","validation","api-migration"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"c5cad058c72f58370553b48566302303cf8a2e89","analyzedAt":"2026-09-01T06:50:53.388Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}