Skip to content
This repository was archived by the owner on Jun 16, 2026. It is now read-only.
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions src/codeweaver/engine/services/reconciliation_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ async def repair_missing_vectors(

return stats

async def _repair_batch(
async def _repair_batch( # noqa: C901
self, collection_name: str, point_ids: list[str], backup_provider: EmbeddingProvider
) -> RepairStats:
"""Repair a batch of points.
Expand Down Expand Up @@ -341,20 +341,36 @@ async def _repair_batch(
return batch_stats

# Update points with backup vectors
for idx, embedding in enumerate(backup_embeddings):
point_id = point_map[idx]
points_to_update = [
{"id": point_map[idx], "vector": {self.backup_vector_name: embedding}}
for idx, embedding in enumerate(backup_embeddings)
]
Comment on lines +344 to +347

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent catch! This is a critical bug. 🎯

The Issue

You're absolutely right. The current code has an index mismatch:

  1. point_map uses the original enumerate(points) index (line 305)
  2. When a point fails validation (line 312-316), it increments idx but doesn't add to chunks
  3. Later, enumerate(backup_embeddings) produces sequential indices [0, 1, 2, ...] (line 346)
  4. These indices don't match the sparse point_map keys β†’ KeyError

Example scenario:

  • Points: [A, B, C, D]
  • Point B fails validation
  • point_map = {0: "A", 2: "C", 3: "D"} ← missing key 1
  • backup_embeddings = [emb_A, emb_C, emb_D]
  • enumerate(backup_embeddings) tries point_map[1] β†’ KeyError

The Fix

Your suggestion is correct. The code should track point IDs alongside chunks:

# Extract CodeChunk objects from payloads
chunks: list[CodeChunk] = []
successful_point_ids: list[str] = []  # Track IDs for successfully validated chunks

for point in points:
    try:
        chunk = CodeChunk.model_validate(point.payload)
        chunks.append(chunk)
        successful_point_ids.append(str(point.id))  # Same order as chunks
    except Exception as e:
        error_msg = f"Failed to extract content from point {point.id}: {e}"
        logger.warning(error_msg)
        batch_stats["failed"] += 1
        batch_stats["errors"].append(error_msg)

# ... generate embeddings ...

# Update points with backup vectors
points_to_update = [
    {"id": point_id, "vector": {self.backup_vector_name: embedding}}
    for point_id, embedding in zip(successful_point_ids, backup_embeddings)
]

This ensures the point IDs and embeddings stay in sync even when some validations fail.

Impact

This bug would cause the entire batch to fail (via uncaught KeyError) if ANY point has invalid payload data, even though the code attempts graceful degradation. The fix ensures partial failures are handled correctly.

cc: /reconciliation_service.py:305-347


if points_to_update:
try:
# Attempt batched update first
await self.vector_store.client.update_vectors(
collection_name=collection_name,
points=[{"id": point_id, "vector": {self.backup_vector_name: embedding}}],
points=points_to_update,
)
batch_stats["repaired"] += 1

except Exception as e:
error_msg = f"Failed to update point {point_id}: {e}"
logger.warning(error_msg)
batch_stats["failed"] += 1
batch_stats["errors"].append(error_msg)
batch_stats["repaired"] += len(points_to_update)

except Exception as batch_e:
logger.warning("Batched update failed, falling back to individual updates: %s", batch_e)
# Fallback to individual updates if batch fails
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
for point in points_to_update:
point_id = point["id"]
try:
await self.vector_store.client.update_vectors(
collection_name=collection_name,
points=[point],
)
batch_stats["repaired"] += 1
except Exception as e:
error_msg = f"Failed to update point {point_id}: {e}"
logger.warning(error_msg)
batch_stats["failed"] += 1
batch_stats["errors"].append(error_msg)

except Exception as e:
error_msg = f"Batch repair failed: {e}"
Expand Down
Loading