{"record":{"id":"61ecad0992cdbc99","repo":"redis/go-redis","slug":"ft-hybrid-vector-blob-is-required","errorCode":null,"errorMessage":"FT.HYBRID: vector blob is required","messagePattern":"FT\\.HYBRID: vector blob is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"search_commands.go","lineNumber":3812,"sourceCode":"\t\treturn hybridVectorBytes(vector.Val)\n\tcase *VectorInt8:\n\t\treturn hybridVectorBytes(vector.Val)\n\tcase *VectorUint8:\n\t\treturn hybridVectorBytes(vector.Val)\n\tcase *VectorValues, *VectorRef:\n\t\treturn nil, fmt.Errorf(\"FT.HYBRID: unsupported vector type %T\", v)\n\tdefault:\n\t\tvalues := v.Value()\n\t\tif len(values) < 2 {\n\t\t\treturn nil, fmt.Errorf(\"FT.HYBRID: vector Value must contain a blob at index 1\")\n\t\t}\n\t\treturn values[1], nil\n\t}\n}\n\nfunc hybridVectorBytes(blob []byte) ([]byte, error) {\n\tif len(blob) == 0 {\n\t\treturn nil, fmt.Errorf(\"FT.HYBRID: vector blob is required\")\n\t}\n\treturn blob, nil\n}\n\n// generateVectorParamName returns a parameter name that is not already present\n// in params. It is used to pass vector data via the PARAMS mechanism when the\n// caller does not provide a VectorParamName, since inline vector blobs are no\n// longer supported by Redis.\nfunc generateVectorParamName(params map[string]interface{}) string {\n\tfor i := 0; ; i++ {\n\t\tname := fmt.Sprintf(\"__vector_param_%d\", i)\n\t\tif _, ok := params[name]; !ok {\n\t\t\treturn name\n\t\t}\n\t}\n}\n\n// FTHybridWithArgs - Executes a hybrid search with advanced options","sourceCodeStart":3794,"sourceCodeEnd":3830,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/search_commands.go#L3794-L3830","documentation":"After resolving the vector to a byte blob, FT.HYBRID requires the blob to be non-empty. hybridVectorBytes rejects empty byte slices so the command is not sent with a zero-length KNN vector.","triggerScenarios":"Calling FTHybridWithArgs with a byte-backed vector whose Val is empty (e.g. &redis.VectorFP32{Val: []float32{}}) or a custom Vector whose Value()[1] is an empty []byte.","commonSituations":"Embedding pipeline returned zero floats on failure; slice truncation bug; deserialized vector struct with nil/empty backing slice.","solutions":["Ensure the vector's byte data is populated (len > 0) before calling FTHybrid.","Validate the embedding output upstream and fail early with your own error.","Check for truncation/serialization bugs that empty the Val slice."],"exampleFix":"// before\nvec := &redis.VectorFP32{Val: []float32{}}\n// after\nif len(embedding) == 0 { return errors.New(\"empty embedding\") }\nvec := &redis.VectorFP32{Val: embedding}","handlingStrategy":"validation","validationCode":"if len(vec.Val) == 0 {\n    return errors.New(\"vector blob is empty\")\n}","typeGuard":"func vectorHasData(v *redis.VectorFP32) bool { return v != nil && len(v.Val) > 0 }","tryCatchPattern":"cmd := client.FTHybridWithArgs(ctx, \"idx\", opts)\nif err := cmd.Err(); err != nil && strings.Contains(err.Error(), \"vector blob is required\") {\n    // regenerate or re-fetch embeddings before retry\n}","preventionTips":["Validate embedding length right after generation","Guard against slice truncation when passing vectors around","Check deserialization paths for nil/empty backing slices"],"tags":["search","vector","ft-hybrid","validation"],"backgroundTag":"missing-required-value","analyzedSha":"c5cad058c72f58370553b48566302303cf8a2e89","analyzedAt":"2026-09-01T06:50:53.388Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}