cocoindex-io/cocoindex · error · ValueError

Column '{column}' has PostgreSQL type '{pg_type}', which is

Error message

Column '{column}' has PostgreSQL type '{pg_type}', which is not a pgvector type.

What it means

Raised by the Postgres connector when declaring a vector index on a column whose PostgreSQL type is not a pgvector type. The library only supports HNSW/IVFFlat indexes on `vector` and `halfvec` columns (checked via `_pgvector_type_base` against `_PGVECTOR_TYPE_BASES`). Any other column type (text, bytea, plain arrays, etc.) cannot carry a pgvector op class, so indexing it as a vector index fails fast.

Source

Thrown at python/cocoindex/connectors/postgres/_target.py:469

_PGVECTOR_OP_CLASS: dict[str, dict[str, str]] = {
    "vector": {
        "cosine": "vector_cosine_ops",
        "l2": "vector_l2_ops",
        "ip": "vector_ip_ops",
    },
    "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

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Check the column name passed to declare_vector_index — verify it in the declared table schema against `self._table_schema.columns`.
  2. Annotate the field with a vector type (e.g. via PgType.Vector or a vector schema annotation) so it maps to the PostgreSQL `vector` type.
  3. If the column is `halfvec`-intended, ensure the type annotation maps to `halfvec` (both are supported).
  4. Remove the declare_vector_index call for columns that genuinely hold non-vector data.

Example fix

// before
table.declare_vector_index(column="description", metric="cosine")  # description is text
// after
table.declare_vector_index(column="description_embedding", metric="cosine")  # vector column
Defensive patterns

Strategy: validation

Validate before calling

def is_pgvector_column(col_type: str) -> bool:
    base = col_type.strip().split("(")[0]
    return base in {"vector", "halfvec"}

# before calling:
# assert is_pgvector_column(schema.columns[col].type)

Type guard

def _is_pgvector_type(pg_type: str) -> bool:
    return pg_type.strip().split('(')[0] in {'vector', 'halfvec'}

Try / catch

try:
    table.declare_vector_index(column=col, metric="cosine")
except ValueError as e:
    if "not a pgvector type" in str(e):
        logger.error("Column %s must be vector/halfvec type", col)
    else:
        raise

Prevention

When it happens

Trigger: Calling `table.declare_vector_index(column=..., metric=...)` where the column's ColumnDef.type (from the table schema) is not `vector` or `halfvec` — e.g. the column was declared as `text[]`, `jsonb`, `bytea`, or an annotated PgType that maps to a non-pgvector type.

Common situations: Pointing declare_vector_index at the wrong column name (a typo selects an id/text column); embedding a column stored as JSON instead of a typed vector column; forgetting the vector type annotation on the field so it maps to a default Postgres type; upgrading from an older schema where the column type changed.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08). Data as JSON: /api/errors/f71e9c356a45029d. Report an issue: GitHub.