Skip to content

Vector Chunk Upserts Can Collide Across Tenants Or Sources

Bug

Chunk creation currently generates content_id from title, content, and chunk index. The async chunker then upserts vector entries by content_id.

Because content_id is not tenant-scoped or source-scoped, two tenants or two sources with identical title/content/chunk index can collide.

Impact

A chunk row can be moved or overwritten across tenants/sources during indexing. That risks incorrect retrieval results, wrong source attribution, and cross-tenant data corruption.

Current Status

Still open. Recent cleanup did not change chunk identity, vector-entry upsert keys, or database uniqueness constraints. This should be solved with the source replacement/versioning work rather than as a standalone quick patch.

This was re-raised in the follow-up Copilot review as the vector content_id collision issue.

Proposed Solution

Make vector chunk identity source-scoped.

Recommended future shape:

  • Use knowledge_source_id + chunk_index as the upsert identity for chunks created from a source.
  • Generate content_id with tenant/source identity included, or treat it as an external identifier rather than the primary upsert key.
  • Add a test where two tenants upload identical content and receive distinct vector rows.
  • Add a test where two sources in the same tenant upload identical content and remain distinct.

This should be handled together with the source replacement and cleanup refactor so old chunks are not accidentally left active.