Skip to content

fix(consolidation): guard _execute_update_action against FK violation on 0-row UPDATE - #3094

Open
ai-ag2026 wants to merge 1 commit into
vectorize-io:mainfrom
ai-ag2026:pr/update-action-fk-guard
Open

fix(consolidation): guard _execute_update_action against FK violation on 0-row UPDATE#3094
ai-ag2026 wants to merge 1 commit into
vectorize-io:mainfrom
ai-ag2026:pr/update-action-fk-guard

Conversation

@ai-ag2026

Copy link
Copy Markdown
Contributor

Summary

If the observation row is concurrently deleted or invalidated, the UPDATE
in _execute_update_action matches 0 rows — and the observation_history
INSERT that follows carries an observation_id FK onto memory_units, so
appending history for the now-missing row raises ForeignKeyViolationError.
Because integrity violations are (correctly) not retried, the consolidation
operation is marked failed for a row that simply no longer exists.

This captures the UPDATE status in the SQL branch and bails out before
writing history when 0 rows matched (debug log). The store branch is an
upsert and cannot hit the 0-row case, so it needs no guard.

Why

Hit in production under concurrent curation: consolidation raced an
invalidation, and the resulting FK violation marked the whole operation
failed. Running with this guard since 2026-07-16.

Validation

Mock-level tests in tests/test_integrity_violation_not_retried.py.
Verified both directions: without the guard two tests go red
(2 failed, 2 passed); with it 4 passed. The file's three
embedded-postgres tests could not run in our sandbox (embedded PG cannot
create TCP sockets there) — they error identically on pristine main, so
that is an environment bound, not an effect of this change.

… on 0-row UPDATE

If the observation row is concurrently deleted or invalidated, the UPDATE
in _execute_update_action matches 0 rows — and the observation_history
INSERT that follows carries an observation_id FK onto memory_units, so
appending history for the now-missing row raises ForeignKeyViolationError.
Because integrity violations are (correctly) not retried, the consolidation
operation is marked failed for a row that simply no longer exists.

Capture the UPDATE status in the SQL branch and bail out before writing
history when 0 rows matched, logging at debug. The store branch is an
upsert and cannot hit the 0-row case.

Tests: mock-level coverage in test_integrity_violation_not_retried.py —
2 tests go red without the guard and green with it. (The three
embedded-postgres tests in that file are environment-bound and behave
identically on pristine main.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant