Production impact
Project info can fail with HTTP 500 when a tenant has a legacy pgvector embeddings table that predates the source_hash column. Cloud surfaces the upstream failure as HTTP 503.
Logfire issue: #2173
Root cause
ProjectService.get_embedding_status() counts physical embeddings with a join on search_vector_embeddings.source_hash. Legacy pgvector tables may exist without that column, so the status read raises asyncpg UndefinedColumnError / SQLAlchemy ProgrammingError before it can recommend a rebuild.
PgVectorIndex.initialize() already detects this legacy schema and owns the repair: it recreates the physical embeddings table and marks chunks pending. The project-info status path can run before index initialization, however, and currently assumes the physical table is current merely because it exists.
This is a code compatibility defect, not expected log noise.
Proposed fix
- inspect the PostgreSQL physical embeddings table schema before executing count queries
- require
source_hash for built-in pgvector storage
- when the column is missing, report vector storage as outdated and recommend
bm reindex --embeddings
- keep the status path read-only; do not drop or rebuild tables from a GET request
- leave external vector adapters and SQLite behavior unchanged
Acceptance criteria
- legacy Postgres storage without
search_vector_embeddings.source_hash returns a status response instead of raising
- the response marks vector tables unavailable/outdated and recommends reindexing
- current pgvector storage still performs the physical count
- external vector adapters and SQLite manifest checks retain their existing behavior
- regression tests cover the legacy schema path
Production impact
Project info can fail with HTTP 500 when a tenant has a legacy pgvector embeddings table that predates the
source_hashcolumn. Cloud surfaces the upstream failure as HTTP 503.Logfire issue:
#21730ffef7ed-d15a-4d36-b020-319d63f86db3ba0cf52630aa4a77881bdc13ef66a21126a303fa9809fb369a763445544ec248690a258323b34834186a7284e29a2a7e39358168de4589d24155332002709f5529c9bdd4937861a4Root cause
ProjectService.get_embedding_status()counts physical embeddings with a join onsearch_vector_embeddings.source_hash. Legacy pgvector tables may exist without that column, so the status read raises asyncpgUndefinedColumnError/ SQLAlchemyProgrammingErrorbefore it can recommend a rebuild.PgVectorIndex.initialize()already detects this legacy schema and owns the repair: it recreates the physical embeddings table and marks chunks pending. The project-info status path can run before index initialization, however, and currently assumes the physical table is current merely because it exists.This is a code compatibility defect, not expected log noise.
Proposed fix
source_hashfor built-in pgvector storagebm reindex --embeddingsAcceptance criteria
search_vector_embeddings.source_hashreturns a status response instead of raising