RyanCodrai/turbovec · error · ValueError
TurboQuantVectorDb supports distance=Distance.cosine or dist
Error message
TurboQuantVectorDb supports distance=Distance.cosine or distance=Distance.max_inner_product; got {distance}. L2 distance is not supported by the underlying inner-product kernel. What it means
The underlying quantized kernel computes inner products, so TurboQuantVectorDb supports only Distance.cosine and Distance.max_inner_product. L2 (euclidean) distance cannot be served correctly and raises a ValueError at construction.
Source
Thrown at turbovec-python/python/turbovec/agno.py:198
similarity_threshold=similarity_threshold,
)
if embedder is None:
raise ValueError(
"`embedder` is required; turbovec needs the embedder's "
"`dimensions` to size the underlying index."
)
if embedder.dimensions is None:
raise ValueError("Embedder.dimensions must be set.")
if bit_width not in (2, 3, 4):
raise ValueError(f"bit_width must be 2, 3, or 4, got {bit_width}")
if search_type != SearchType.vector:
raise ValueError(
f"TurboQuantVectorDb only supports search_type=SearchType.vector; "
f"got {search_type}. Use LanceDb / Chroma / etc. for keyword "
f"or hybrid search."
)
if distance not in (Distance.cosine, Distance.max_inner_product):
raise ValueError(
f"TurboQuantVectorDb supports distance=Distance.cosine or "
f"distance=Distance.max_inner_product; got {distance}. "
f"L2 distance is not supported by the underlying "
f"inner-product kernel."
)
self.embedder: Embedder = embedder
self.dimensions: int = embedder.dimensions
self.bit_width = bit_width
# Assigned through the validating property below, so the guard
# applies to runtime mutation as well as construction.
self.search_type = search_type
self.distance = distance
self.reranker = reranker
self.path: Optional[str] = path
# Lazy: the underlying IdMapIndex is created by `create()`, not
# in __init__. This matches LanceDb's `exists()` contract: aView on GitHub (pinned to ccab9f325e)
Solutions
- Set distance=Distance.cosine (most common for text embeddings).
- Use distance=Distance.max_inner_product if your scores are inner-product-like (e.g. MIPS).
- If L2 is mandatory, choose a backend whose kernel supports euclidean distance.
Example fix
// before TurboQuantVectorDb(embedder=e, distance=Distance.l2) // after TurboQuantVectorDb(embedder=e, distance=Distance.cosine)
Defensive patterns
Strategy: validation
Validate before calling
from agno.vectordb.distance import Distance
if distance not in (Distance.cosine, Distance.max_inner_product):
distance = Distance.cosine Try / catch
try:
db = TurboQuantVectorDb(embedder=e, distance=d)
except ValueError:
db = TurboQuantVectorDb(embedder=e, distance=Distance.cosine) Prevention
- Default to Distance.cosine for text-embedding workloads.
- Do not copy distance settings from L2-based backends (Milvus/LanceDb defaults).
- Centralize backend construction so distance is set per-backend, not globally.
When it happens
Trigger: TurboQuantVectorDb(..., distance=Distance.l2) or any distance value other than cosine / max_inner_product.
Common situations: Reusing a distance enum copied from LanceDb/Milvus configs that default to L2; assuming euclidean distance is universally supported; porting pipelines tuned for L2-normalized-with-L2 setups.
Related errors
- TurboQuantVectorDb only supports search_type=SearchType.vect
- {param} must be one of {list(_VALID_MODES)}, got {value!r}
- Embedder.dimensions must be set.
- bit_width must be 2, 3, or 4, got {bit_width}
AI-assisted analysis of RyanCodrai/turbovec@ccab9f325e (2026-09-06).
Data as JSON: /api/errors/1d563667f3b1238d.
Report an issue: GitHub.