cocoindex-io/cocoindex · error · RuntimeError
Failed to add column {col_name!r} to SQLite table {table_nam
Error message
Failed to add column {col_name!r} to SQLite table {table_name!r}: {e} What it means
When applying an `add` column action, `_apply_column_actions` runs `ALTER TABLE ... ADD COLUMN`. If SQLite raises `OperationalError` for any reason other than 'duplicate column name' (which is tolerated as idempotent re-run), the error is wrapped in a `RuntimeError` naming the column and table.
Source
Thrown at python/cocoindex/connectors/sqlite/_target.py:848
if desired_col is None:
# If the desired schema no longer mentions this column, treat
# it as a no-op here; "delete" should have been emitted.
continue
if action in ("insert", "upsert"):
# SQLite supports ADD COLUMN
nullable = "" if desired_col.nullable else " NOT NULL"
try:
conn.execute(
f"ALTER TABLE {qualified_name} "
f'ADD COLUMN "{col_name}" {desired_col.type}{nullable}'
)
except sqlite3.OperationalError as e:
# Only ignore if column already exists (e.g. upsert / idempotent re-run)
if "duplicate column name" in str(e).lower():
pass
else:
raise RuntimeError(
f"Failed to add column {col_name!r} to SQLite table {table_name!r}: {e}"
) from e
continue
if action == "replace":
# SQLite doesn't support ALTER COLUMN TYPE directly.
# For type changes, attempt to drop and re-add column.
try:
conn.execute(f'ALTER TABLE {qualified_name} DROP COLUMN "{col_name}"')
except sqlite3.OperationalError:
pass
nullable = "" if desired_col.nullable else " NOT NULL"
try:
conn.execute(
f"ALTER TABLE {qualified_name} "
f'ADD COLUMN "{col_name}" {desired_col.type}{nullable}'
)
except sqlite3.OperationalError as e:View on GitHub (pinned to e84aa99b32)
Solutions
- Read the wrapped SQLite message (`{e}`) to identify the underlying ALTER TABLE failure
- Make the new column nullable or provide a default so SQLite's ADD COLUMN restrictions are satisfied
- Fix the column type mapping (SqliteType / VectorSchemaProvider override) to a valid SQLite type
- Ensure no concurrent process is mutating the same table during sync
Example fix
// before (column override forcing invalid/strict add)
column_overrides={"embedding": sqlite.SqliteType.FLOAT_VECTOR(dim=0)}
// after
column_overrides={"embedding": sqlite.VectorSchemaProvider(dim=768)} Defensive patterns
Strategy: try-catch
Validate before calling
# validate override types before sync
for name, ov in column_overrides.items():
assert ov is not None and name in schema_fields Try / catch
try:
await app.update()
except RuntimeError as e:
if str(e).startswith("Failed to add column"):
log_sqlite_detail(e.__cause__)
# fix column type/nullability, then retry
else:
raise Prevention
- Keep record field types mappable to valid SQLite types
- Make newly added columns nullable or defaulted
- Avoid concurrent writers on the same SQLite file during sync
When it happens
Trigger: Adding a column whose SQLite type is invalid or unsupported; attempting to add a non-nullable PRIMARY KEY/UNIQUE column (SQLite restriction); the table name colliding with an internal alias or a reserved name; a concurrently dropped table.
Common situations: Schema evolution where the new column's derived SqliteType is malformed (e.g. a bad vector dimension); adding a column declared `nullable=False` with a PRIMARY KEY constraint; running two syncs concurrently on the same database file.
Related errors
- Failed to replace column {col_name!r} in SQLite table {table
- Unexpected column subkey format: {sub_key!r}, expected to st
- row_count must be positive
- Invalid identifier: {name}
- Invalid table name format: {table}
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/a15dd285b0f8cfd6.
Report an issue: GitHub.