abhigyanpatwari/GitNexus · critical · Error
[embed] Failed to delete stale embedding rows — aborting to
Error message
[embed] Failed to delete stale embedding rows — aborting to prevent vector-index corruption: ${msg} What it means
Thrown by deleteStaleEmbeddingRows() when a Cypher DELETE against the embedding table fails with an error that is NOT a benign 'does not exist' (which means the rows were already gone). Kuzu forbids SET on vector-indexed properties, so re-embedding uses DELETE-then-INSERT; a failed DELETE that isn't the already-gone case risks leaving the vector index in a corrupted half-state, so the pipeline aborts rather than continuing to INSERT over potentially-stale or dangling rows. Called per-batch to bound the re-embed window.
Source
Thrown at gitnexus/src/core/embeddings/embedding-pipeline.ts:509
* interleaving bounds that window to a single batch.
*/
const deleteStaleEmbeddingRows = async (
executeWithReusedStatement: (
cypher: string,
paramsList: Array<Record<string, any>>,
) => Promise<void>,
nodeIds: string[],
): Promise<void> => {
if (nodeIds.length === 0) return;
try {
await executeWithReusedStatement(
`MATCH (e:${EMBEDDING_TABLE_NAME} {nodeId: $nodeId}) DELETE e`,
nodeIds.map((nodeId) => ({ nodeId })),
);
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
if (!msg.includes('does not exist')) {
throw new Error(
`[embed] Failed to delete stale embedding rows — aborting to prevent vector-index corruption: ${msg}`,
);
}
}
};
/**
* Run the embedding pipeline
*
* @param executeQuery - Function to execute Cypher queries against LadybugDB
* @param executeWithReusedStatement - Function to execute with reused prepared statement
* @param onProgress - Callback for progress updates
* @param config - Optional configuration override
* @param skipNodeIds - Optional set of node IDs that already have embeddings (incremental mode)
* @param existingEmbeddings - Optional map of nodeId → contentHash for incremental mode.
* Nodes whose hash matches are skipped; nodes with a changed hash are DELETE'd
* and re-embedded; nodes not in the map are embedded fresh.
*/View on GitHub (pinned to d540b00184)
Solutions
- Run `gitnexus clean` to reset the index and re-run analyze --embeddings from a clean state.
- Ensure no other analyze/serve process is writing to the same .gitnexus index concurrently.
- If running in a container, check for the known LadybugDB file-locking issue and use a volume that supports flock.
- Capture the full underlying error (the ${msg}) — if it indicates a schema/extension problem, address that before retrying.
Example fix
# before — corrupt/half-deleted vector index blocks re-embed $ npx gitnexus analyze --embeddings # after — reset and re-embed cleanly $ npx gitnexus clean $ npx gitnexus analyze --embeddings
Defensive patterns
Strategy: try-catch
Type guard
const isVectorIndexCorruptionRisk = (msg: string): boolean =>
msg.includes('Failed to delete stale embedding rows'); Try / catch
try {
await runEmbeddingPipeline(executeQuery, executeWithReusedStatement, onProgress);
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
if (msg.includes('Failed to delete stale embedding rows')) {
console.error('Vector index at risk of corruption. Run `gitnexus clean` then re-analyze.');
process.exit(1);
}
throw err;
} Prevention
- Do not run two analyze processes against the same .gitnexus index concurrently.
- Run `gitnexus clean` after a crashed analysis before re-running.
- In containers, use a volume that supports flock to avoid LadybugDB file-lock failures.
When it happens
Trigger: Any error from executeWithReusedStatement during the per-batch stale-row cleanup whose message lacks 'does not exist': a LadybugDB/Kuzu connection drop, a transaction conflict, a schema mismatch, a vector extension in a bad state, or a concurrent writer.
Common situations: A LadybugDB file lock contention (known container issue per AGENTS.md); the vector index in an inconsistent state after a crashed previous run; concurrent analyze processes against one index; a Kuzu version upgrade changing error wording.
Related errors
- checkpointEveryNodes must be a positive integer
- LadybugDB WAL corruption detected at ${dbPath}. WAL corrupti
- ${source} must be true/false or a non-negative integer (node
- ${source} must be a boolean or a non-negative integer (node
- ${name} must be a positive integer, got "${value}"
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/deb9711751e33d24.
Report an issue: GitHub.