redis/go-redis · error
FT.HYBRID: vector Value must contain a blob at index 1
Error message
FT.HYBRID: vector Value must contain a blob at index 1
What it means
For a custom Vector implementation in FT.HYBRID, the client calls Value() and expects [paramName, blob] with the raw binary vector data at index 1. If the returned slice has fewer than 2 elements, there is no blob to send and this error is returned.
Source
Thrown at search_commands.go:3804
switch vector := v.(type) {
case *VectorFP32:
return hybridVectorBytes(vector.Val)
case *VectorFloat16:
return hybridVectorBytes(vector.Val)
case *VectorBFloat16:
return hybridVectorBytes(vector.Val)
case *VectorFloat64:
return hybridVectorBytes(vector.Val)
case *VectorInt8:
return hybridVectorBytes(vector.Val)
case *VectorUint8:
return hybridVectorBytes(vector.Val)
case *VectorValues, *VectorRef:
return nil, fmt.Errorf("FT.HYBRID: unsupported vector type %T", v)
default:
values := v.Value()
if len(values) < 2 {
return nil, fmt.Errorf("FT.HYBRID: vector Value must contain a blob at index 1")
}
return values[1], nil
}
}
func hybridVectorBytes(blob []byte) ([]byte, error) {
if len(blob) == 0 {
return nil, fmt.Errorf("FT.HYBRID: vector blob is required")
}
return blob, nil
}
// generateVectorParamName returns a parameter name that is not already present
// in params. It is used to pass vector data via the PARAMS mechanism when the
// caller does not provide a VectorParamName, since inline vector blobs are no
// longer supported by Redis.
func generateVectorParamName(params map[string]interface{}) string {
for i := 0; ; i++ {View on GitHub (pinned to c5cad058c7)
Solutions
- Return at least two elements from Value(), with the encoded binary vector as element 1.
- Reuse a built-in blob type like *VectorFP32 to avoid implementing Value() yourself.
- Encode floats to little-endian bytes (or use VectorFP32's encoding) before returning them.
Example fix
// before
func (v *myVec) Value() []interface{} { return []interface{}{"vec_param"} }
// after
func (v *myVec) Value() []interface{} { return []interface{}{"vec_param", float32LEBytes(v.data)} } Defensive patterns
Strategy: validation
Validate before calling
vals := myVec.Value()
if len(vals) < 2 {
return errors.New("custom Vector.Value() must return [name, blob]")
} Type guard
func customVectorOK(v redis.Vector) bool {
return len(v.Value()) >= 2
} Try / catch
cmd := client.FTHybridWithArgs(ctx, "idx", opts)
if err := cmd.Err(); err != nil && strings.Contains(err.Error(), "blob at index 1") {
// fix Value() implementation before retrying
} Prevention
- Follow the [paramName, blob] contract in custom Vector implementations
- Add a unit test asserting Value() arity
- Prefer built-in blob types over custom implementations
When it happens
Trigger: Passing a custom Vector type to FTHybridWithArgs whose Value() returns a slice of length 0 or 1 (e.g. only the parameter name, or an empty slice).
Common situations: Custom Vector implementations written for another command's contract returning just the float values; forgetting that FT.HYBRID needs name-then-blob ordering.
Related errors
- FT.HYBRID: vector data is required
- FT.HYBRID: unsupported vector type %T
- FT.HYBRID: vector blob is required
- FT.HYBRID: SHARD_K_RATIO requires KNN method
- FT.HYBRID: SHARD_K_RATIO must be between 0.1 and 1.0
AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01).
Data as JSON: /api/errors/74955371615f57ce.
Report an issue: GitHub.