cocoindex-io/cocoindex · error · ValueError
vec0 virtual tables require INTEGER primary key, got {pk_col
Error message
vec0 virtual tables require INTEGER primary key, got {pk_col_type} for column '{pk_col_name}' What it means
vec0 virtual tables require the single primary key column to be of SQLite type INTEGER (rowid-style). The primary key column's declared type is something else (TEXT, BLOB, REAL, etc.), so CocoIndex rejects it during vec0 validation.
Source
Thrown at python/cocoindex/connectors/sqlite/_target.py:1154
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,
virtual_table_def: Vec0TableDef | None = None,
) -> "coco.TargetState[_RowHandler]":
"""
Create a TargetState for a SQLite table target.
Use with ``coco.mount_target()`` to mount and get a child provider,
or with ``declare_table_target()`` / ``mount_table_target()`` for convenience wrappers.View on GitHub (pinned to e84aa99b32)
Solutions
- Declare the primary key column as INTEGER (int in Python) in the schema.
- If you need string/UUID keys, make an INTEGER auto-increment id the primary key and store the UUID in a separate column.
- Check the column type mapping used when building the schema and ensure the PK maps to SQLite 'INTEGER'.
Example fix
// before
schema = table_schema(columns={"id": "TEXT", "embedding": "float[768]"}, primary_key=["id"])
// after
schema = table_schema(columns={"id": "INTEGER", "doc_uuid": "TEXT", "embedding": "float[768]"}, primary_key=["id"]) Defensive patterns
Strategy: type-guard
Validate before calling
pk = schema.primary_key[0]
if schema.columns[pk].type != "INTEGER":
raise ValueError("vec0 primary key must be INTEGER") Type guard
def pk_is_integer(schema) -> bool:
pk = schema.primary_key[0]
return schema.columns[pk].type == "INTEGER" Try / catch
try:
target = table_target(schema, virtual_table_def)
except ValueError as e:
if "INTEGER primary key" in str(e):
# switch PK column to INTEGER or move string key to a separate column
... Prevention
- Always use int/INTEGER for vec0 primary keys; store UUIDs in a separate TEXT column.
- Verify type mappings when building schemas for SQLite.
- Add a schema linter/test that asserts PK type before creating vec0 tables.
When it happens
Trigger: Calling table_target() for a vec0 table whose single primary key column has a non-INTEGER type, e.g. primary_key=["id"] with id declared as TEXT/str (UUID strings) or REAL (float ids).
Common situations: Using UUID or string identifiers as primary keys, a habit from other databases; declaring the id column without a type so it defaults to non-INTEGER; migrating a schema from Postgres where SERIAL/BIGINT mapped to a non-INTEGER SQLite name.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- vec0 virtual tables require exactly one primary key column,
- VectorSchemaProvider is only supported for NumPy ndarray typ
- Primary key column '{pk}' not found in columns: {list(self.c
- record_type must be a record type (dataclass, NamedTuple, Py
- SQLite row is missing primary key column {pk!r}
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/dd42f0ad81c11735.
Report an issue: GitHub.