{"id":"96d6876dd9c40f2e","repo":"go-redis/redis","slug":"ft-create-type-dim-and-distancemetric-are-requir-96d687","errorCode":null,"errorMessage":"FT.CREATE: Type, Dim and DistanceMetric are required for VECTOR HNSW","messagePattern":"FT\\.CREATE: Type, Dim and DistanceMetric are required for VECTOR HNSW","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"search_commands.go","lineNumber":1510,"sourceCode":"\t\t\t\tflatArgs := []interface{}{\n\t\t\t\t\t\"TYPE\", schema.VectorArgs.FlatOptions.Type,\n\t\t\t\t\t\"DIM\", schema.VectorArgs.FlatOptions.Dim,\n\t\t\t\t\t\"DISTANCE_METRIC\", schema.VectorArgs.FlatOptions.DistanceMetric,\n\t\t\t\t}\n\t\t\t\tif schema.VectorArgs.FlatOptions.InitialCapacity > 0 {\n\t\t\t\t\tflatArgs = append(flatArgs, \"INITIAL_CAP\", schema.VectorArgs.FlatOptions.InitialCapacity)\n\t\t\t\t}\n\t\t\t\tif schema.VectorArgs.FlatOptions.BlockSize > 0 {\n\t\t\t\t\tflatArgs = append(flatArgs, \"BLOCK_SIZE\", schema.VectorArgs.FlatOptions.BlockSize)\n\t\t\t\t}\n\t\t\t\targs = append(args, len(flatArgs))\n\t\t\t\targs = append(args, flatArgs...)\n\t\t\t}\n\t\t\tif schema.VectorArgs.HNSWOptions != nil {\n\t\t\t\targs = append(args, \"HNSW\")\n\t\t\t\tif schema.VectorArgs.HNSWOptions.Type == \"\" || schema.VectorArgs.HNSWOptions.Dim == 0 || schema.VectorArgs.HNSWOptions.DistanceMetric == \"\" {\n\t\t\t\t\tcmd := NewStatusCmd(ctx, args...)\n\t\t\t\t\tcmd.SetErr(fmt.Errorf(\"FT.CREATE: Type, Dim and DistanceMetric are required for VECTOR HNSW\"))\n\t\t\t\t\treturn cmd\n\t\t\t\t}\n\t\t\t\thnswArgs := []interface{}{\n\t\t\t\t\t\"TYPE\", schema.VectorArgs.HNSWOptions.Type,\n\t\t\t\t\t\"DIM\", schema.VectorArgs.HNSWOptions.Dim,\n\t\t\t\t\t\"DISTANCE_METRIC\", schema.VectorArgs.HNSWOptions.DistanceMetric,\n\t\t\t\t}\n\t\t\t\tif schema.VectorArgs.HNSWOptions.InitialCapacity > 0 {\n\t\t\t\t\thnswArgs = append(hnswArgs, \"INITIAL_CAP\", schema.VectorArgs.HNSWOptions.InitialCapacity)\n\t\t\t\t}\n\t\t\t\tif schema.VectorArgs.HNSWOptions.MaxEdgesPerNode > 0 {\n\t\t\t\t\thnswArgs = append(hnswArgs, \"M\", schema.VectorArgs.HNSWOptions.MaxEdgesPerNode)\n\t\t\t\t}\n\t\t\t\tif schema.VectorArgs.HNSWOptions.MaxAllowedEdgesPerNode > 0 {\n\t\t\t\t\thnswArgs = append(hnswArgs, \"EF_CONSTRUCTION\", schema.VectorArgs.HNSWOptions.MaxAllowedEdgesPerNode)\n\t\t\t\t}\n\t\t\t\tif schema.VectorArgs.HNSWOptions.EFRunTime > 0 {\n\t\t\t\t\thnswArgs = append(hnswArgs, \"EF_RUNTIME\", schema.VectorArgs.HNSWOptions.EFRunTime)","sourceCodeStart":1492,"sourceCodeEnd":1528,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/search_commands.go#L1492-L1528","documentation":"Returned by FTCreate when HNSWOptions is selected but Type, Dim, or DistanceMetric is unset. These three are mandatory for a VECTOR HNSW index; tuning knobs (M, EF_CONSTRUCTION, etc.) are optional. The guard is at search_commands.go:1508.","triggerScenarios":"Constructing &redis.FTHNSWOptions{} missing Type, Dim (==0), or DistanceMetric (==\"\"). Often only the tuning parameters are set while the required trio is overlooked.","commonSituations":"Copy-pasting an HNSW config that sets M and EF_RUNTIME but not the base triplet, or deriving Dim from an embedding library whose value is 0 before model load.","solutions":["Set HNSWOptions.Type, HNSWOptions.Dim (>0), and HNSWOptions.DistanceMetric on every HNSW vector field.","Keep a shared helper that returns a fully-populated HNSW options struct given (dim, metric).","Assert Dim matches your embedding dimensionality at startup."],"exampleFix":"// before\n&redis.FTHNSWOptions{Type: \"FLOAT32\", MaxEdgesPerNode: 16}\n\n// after\n&redis.FTHNSWOptions{Type: \"FLOAT32\", Dim: 768, DistanceMetric: \"COSINE\", MaxEdgesPerNode: 16}","handlingStrategy":"validation","validationCode":"o := f.VectorArgs.HNSWOptions\nif o.Type == \"\" || o.Dim == 0 || o.DistanceMetric == \"\" {\n    return fmt.Errorf(\"HNSW vector field %q needs Type, Dim>0, DistanceMetric\", f.FieldName)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set the required Type/Dim/DistanceMetric trio even when tuning M/EF.","Share a helper that fills the trio from (dim, metric).","Verify Dim matches your embedding dimensionality."],"tags":["redisearch","ft-create","vector","hnsw","validation"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}