go-redis/redis · error
FT.CREATE: SCHEMA VectorArgs must have exactly one of FlatOp
Error message
FT.CREATE: SCHEMA VectorArgs must have exactly one of FlatOptions, HNSWOptions, or VamanaOptions
What it means
Returned by FTCreate when FTVectorArgs does not have exactly one of FlatOptions, HNSWOptions, or VamanaOptions set. RediSearch requires a single vector algorithm choice; setting zero (no algorithm) or more than one (ambiguous) is rejected client-side at search_commands.go:1480.
Source
Thrown at search_commands.go:1482
if schema.FieldType != SearchFieldTypeVector {
cmd := NewStatusCmd(ctx, args...)
cmd.SetErr(fmt.Errorf("FT.CREATE: SCHEMA FieldType VECTOR is required for VectorArgs"))
return cmd
}
// Check mutual exclusivity of vector options
optionCount := 0
if schema.VectorArgs.FlatOptions != nil {
optionCount++
}
if schema.VectorArgs.HNSWOptions != nil {
optionCount++
}
if schema.VectorArgs.VamanaOptions != nil {
optionCount++
}
if optionCount != 1 {
cmd := NewStatusCmd(ctx, args...)
cmd.SetErr(fmt.Errorf("FT.CREATE: SCHEMA VectorArgs must have exactly one of FlatOptions, HNSWOptions, or VamanaOptions"))
return cmd
}
if schema.VectorArgs.FlatOptions != nil {
args = append(args, "FLAT")
if schema.VectorArgs.FlatOptions.Type == "" || schema.VectorArgs.FlatOptions.Dim == 0 || schema.VectorArgs.FlatOptions.DistanceMetric == "" {
cmd := NewStatusCmd(ctx, args...)
cmd.SetErr(fmt.Errorf("FT.CREATE: Type, Dim and DistanceMetric are required for VECTOR FLAT"))
return cmd
}
flatArgs := []interface{}{
"TYPE", schema.VectorArgs.FlatOptions.Type,
"DIM", schema.VectorArgs.FlatOptions.Dim,
"DISTANCE_METRIC", schema.VectorArgs.FlatOptions.DistanceMetric,
}
if schema.VectorArgs.FlatOptions.InitialCapacity > 0 {
flatArgs = append(flatArgs, "INITIAL_CAP", schema.VectorArgs.FlatOptions.InitialCapacity)
}
if schema.VectorArgs.FlatOptions.BlockSize > 0 {View on GitHub (pinned to 36d97525cd)
Solutions
- Set exactly one of FlatOptions, HNSWOptions, or VamanaOptions on FTVectorArgs.
- Reset the unused algorithm pointers to nil when switching algorithms at runtime.
- Use a builder/switch that assigns one option struct and leaves the others nil.
Example fix
// before (two set)
&redis.FTVectorArgs{FlatOptions: f, HNSWOptions: h}
// after (exactly one)
&redis.FTVectorArgs{HNSWOptions: h} Defensive patterns
Strategy: validation
Validate before calling
func countVecOpts(v *redis.FTVectorArgs) int {
n := 0
if v.FlatOptions != nil { n++ }
if v.HNSWOptions != nil { n++ }
if v.VamanaOptions != nil { n++ }
return n
}
if n := countVecOpts(f.VectorArgs); n != 1 {
return fmt.Errorf("exactly one vector algorithm required, got %d", n)
} Prevention
- Assign exactly one of Flat/HNSW/Vamana; nil the others when switching.
- Build vector options through a switch that sets only the chosen algorithm.
- Add an assertion in tests that optionCount==1 for every vector field.
When it happens
Trigger: Constructing FTVectorArgs{} with no options set, or populating two option structs (e.g. FlatOptions and HNSWOptions) simultaneously. The optionCount counter at line 1470 must equal exactly 1.
Common situations: Conditionally building options where a switch falls through leaving none set, or merging configs that accidentally set multiple algorithm options. Also happens when migrating between algorithms and forgetting to nil the old field.
Related errors
- FT.CREATE: SCHEMA FieldType VECTOR is required for VectorArg
- FT.CREATE: SCHEMA is required
- FT.CREATE: SCHEMA FieldName and FieldType are required
- FT.CREATE: Type, Dim and DistanceMetric are required for VEC
- FT.CREATE: Type, Dim and DistanceMetric are required for VEC
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/c253d5b657330c36.json.
Report an issue: GitHub.