Skip to content

fix(drizzle): preserve failing sub-table on unique-constraint ValidationError#17014

Open
GermanJablo wants to merge 2 commits into
mainfrom
fix/upsert-error-subtable-path
Open

fix(drizzle): preserve failing sub-table on unique-constraint ValidationError#17014
GermanJablo wants to merge 2 commits into
mainfrom
fix/upsert-error-subtable-path

Conversation

@GermanJablo

Copy link
Copy Markdown
Contributor

What?

When a database-level unique-constraint violation (Postgres 23505 / SQLite SQLITE_CONSTRAINT_UNIQUE) is raised on an array/block sub-table and converted into a ValidationError in handleUpsertError, only the bare column name (typically id) was preserved. The failing sub-table name and original constraint detail were discarded.

As a result:

  • Editors see an unhelpful "The following field is invalid: id", with no indication of which array/block row or collection field is affected.
  • afterError hooks cannot enrich the message, because by the time they run ValidationError.data only contains path: "id".

Closes #16965.

How?

handleUpsertError already receives the failing tableName. This PR adds an optional tableName to ValidationFieldError and populates it when throwing the constraint ValidationError, so afterError hooks can map the failure back to a collection field/block.

The dotted field path is intentionally not resolved at insert time. The previous attempt (#15754) did that by switching from a batch insert to per-row inserts to recover a per-row block path, and it was closed by its author because it caused data loss. This change is purely diagnostic and does not touch how rows are inserted.

Notes

Tests

  • Adds handleUpsertError.spec.ts (unit): asserts a 23505 on an array sub-table throws a ValidationError carrying tableName, and that non-constraint errors are re-thrown unchanged.

…ionError

When a Postgres/SQLite unique-constraint violation on an array/block
sub-table is converted into a ValidationError, only the bare column name
(typically `id`) was preserved, so editors saw "The following field is
invalid: id" and afterError hooks had no way to identify the affected
field/block.

`handleUpsertError` already knows the failing `tableName`; this exposes it
on the thrown ValidationError's field error so afterError hooks can map the
failure back to a collection field/block. The dotted field path is
deliberately not resolved at insert time: doing that required per-row
inserts and caused data loss in the previous attempt (#15754). This change
does not touch insert mechanics.
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

📦 esbuild Bundle Analysis for payload

This analysis was generated by esbuild-bundle-analyzer. 🤖
This PR introduced no changes to the esbuild bundle! 🙌

@GermanJablo GermanJablo enabled auto-merge (squash) June 16, 2026 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

db-postgres: preserve sub-table and block path on unique-constraint ValidationError so the UI can highlight the field

1 participant