cocoindex-io/cocoindex · error · ValueError
vec0 virtual tables require exactly one primary key column,
Error message
vec0 virtual tables require exactly one primary key column, got {len(table_schema.primary_key)}: {table_schema.primary_key} What it means
sqlite-vec vec0 virtual tables require exactly one primary key column. The provided table schema declares zero or multiple primary key columns, so CocoIndex rejects the configuration before creating the table.
Source
Thrown at python/cocoindex/connectors/sqlite/_target.py:1147
"sqlite-vec extension must be loaded for vec0 virtual tables. "
"Use connect(..., load_vec=True)"
)
has_vector_col = any(
col_def.type.startswith("float[") for col_def in table_schema.columns.values()
)
if not has_vector_col:
raise ValueError(
"vec0 virtual tables require at least one float[N] vector column"
)
all_cols = set(table_schema.columns.keys())
invalid_partition = set(virtual_table_def.partition_key_columns) - all_cols
if invalid_partition:
raise ValueError(f"Partition key columns not in schema: {invalid_partition}")
invalid_aux = set(virtual_table_def.auxiliary_columns) - all_cols
if invalid_aux:
raise ValueError(f"Auxiliary columns not in schema: {invalid_aux}")
if len(table_schema.primary_key) != 1:
raise ValueError(
f"vec0 virtual tables require exactly one primary key column, "
f"got {len(table_schema.primary_key)}: {table_schema.primary_key}"
)
pk_col_name = table_schema.primary_key[0]
pk_col_type = table_schema.columns[pk_col_name].type
if pk_col_type != "INTEGER":
raise ValueError(
f"vec0 virtual tables require INTEGER primary key, "
f"got {pk_col_type} for column '{pk_col_name}'"
)
def table_target(
db: ContextKey[ManagedConnection],
table_name: str,
table_schema: TableSchema[RowT],
*,
managed_by: target.ManagedBy = target.ManagedBy.SYSTEM,View on GitHub (pinned to e84aa99b32)
Solutions
- Change the schema so exactly one column is the primary key.
- Move extra key columns to regular columns or partition key columns instead.
- If no PK was intended, explicitly mark one existing column (e.g. an INTEGER id) as primary key.
Example fix
// before schema = table_schema(primary_key=["id", "doc_id"]) // after schema = table_schema(primary_key=["id"], columns=["id", "doc_id", "embedding"])
Defensive patterns
Strategy: validation
Validate before calling
if len(schema.primary_key) != 1:
raise ValueError("vec0 tables need exactly one primary key column") Type guard
def has_single_pk(schema) -> bool:
return len(schema.primary_key) == 1 Try / catch
try:
target = table_target(schema, virtual_table_def)
except ValueError as e:
if "exactly one primary key" in str(e):
schema = replace_primary_key(schema, ["id"])
... Prevention
- Never use composite primary keys with vec0 tables; use one INTEGER PK plus indexed regular columns.
- Check primary_key length when reusing shared schema builders.
- Document the single-PK constraint in table definition helpers.
When it happens
Trigger: Calling table_target() for a vec0 table where table_schema.primary_key has length != 1 (composite PK like ["id", "ts"], or no PK at all).
Common situations: Defining a composite primary key as in normal SQLite/Postgres tables, then reusing the schema for a vec0 table; forgetting to mark any column as primary key when building the schema manually.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- vec0 virtual tables require at least one float[N] vector col
- Partition key columns not in schema: {invalid_partition}
- Auxiliary columns not in schema: {invalid_aux}
- vec0 virtual tables require INTEGER primary key, got {pk_col
- Primary key column '{pk}' not found in columns: {list(self.c
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/309302761c267283.
Report an issue: GitHub.