cocoindex-io/cocoindex · error · ValueError
Unsupported pgvector metric '{metric}' for PostgreSQL type '
Error message
Unsupported pgvector metric '{metric}' for PostgreSQL type '{pg_type}'. What it means
Raised by `_pgvector_op_class` when the requested similarity metric has no entry in `_PGVECTOR_OP_CLASS` for the column's pgvector type base (`vector` or `halfvec`). Each pgvector type supports a fixed set of metrics (cosine, l2, ip); anything else (e.g. 'dot', 'euclidean', 'hamming') is rejected.
Source
Thrown at python/cocoindex/connectors/postgres/_target.py:476
"halfvec": {
"cosine": "halfvec_cosine_ops",
"l2": "halfvec_l2_ops",
"ip": "halfvec_ip_ops",
},
}
def _pgvector_op_class(column: str, pg_type: str, metric: str) -> str:
type_base = _pgvector_type_base(pg_type)
if type_base is None:
raise ValueError(
f"Column '{column}' has PostgreSQL type '{pg_type}', which is not a pgvector type."
)
try:
return _PGVECTOR_OP_CLASS[type_base][metric]
except KeyError as e:
raise ValueError(
f"Unsupported pgvector metric '{metric}' for PostgreSQL type '{pg_type}'."
) from e
class _VectorIndexSpec(NamedTuple):
column: str
metric: str
op_class: str
method: str
lists: int | None
m: int | None
ef_construction: int | None
_VectorIndexFingerprint = bytes
class _VectorIndexAction(NamedTuple):View on GitHub (pinned to e84aa99b32)
Solutions
- Use one of the supported metric strings: 'cosine', 'l2', or 'ip'.
- Map your desired metric: dot product -> 'ip', euclidean -> 'l2', cosine similarity -> 'cosine'.
- Lowercase the metric string before passing it.
- Check `_PGVECTOR_OP_CLASS` in the connector source for the exact supported matrix.
Example fix
// before table.declare_vector_index(column="embedding", metric="Euclid") // after table.declare_vector_index(column="embedding", metric="l2")
Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED_METRICS = {"cosine", "l2", "ip"}
# before calling:
# assert metric.lower() in SUPPORTED_METRICS Type guard
from typing import Literal
Metric = Literal["cosine", "l2", "ip"]
def is_metric(m: str) -> bool:
return m in {"cosine", "l2", "ip"} Try / catch
try:
table.declare_vector_index(column=col, metric=metric)
except ValueError as e:
if "Unsupported pgvector metric" in str(e):
logger.error("Metric %r invalid; use cosine/l2/ip", metric)
else:
raise Prevention
- Define metric names once as module-level constants and reuse them.
- Map vendor-specific metric names (Euclid/Dot) to pgvector names in one helper.
- Always lowercase and normalize the metric string.
When it happens
Trigger: Calling `declare_vector_index(column=..., metric='dot')` or any metric string other than exactly 'cosine', 'l2', or 'ip' on a vector/halfvec column; a typo like 'cosine_distance' or mixed-case 'Cosine'.
Common situations: Translating metric names from another vector database (Qdrant's 'Euclid'/'Dot') into this API; case-sensitivity mistakes; passing an enum's repr instead of the string.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Column '{column}' has PostgreSQL type '{pg_type}', which is
- Unsupported metric type: {metric!r}
- Unsupported LanceDB vector index type: {spec.index_type!r}.
- asyncpg is required to use the PostgreSQL source connector.
- {identifier_type} cannot be empty
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/c0527ed067bd552b.
Report an issue: GitHub.