You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A block add through the admin UI persisted a sparse blocks array to Postgres: the surviving rows kept their original array indexes (_order 1 and 3) with no row at _order 2. On every subsequent read, Payload rehydrates the gap as an undefined array entry, and the form-state builder throws:
Block with type "undefined" was found in block data, but no block with that type is defined in the config for field with schema path promotionListings.layout.
The result is that the entire edit view for the document fails to load in the affected locale — editors are locked out of the document until the underlying rows are repaired (a draft save that happens to rewrite the array also clears it).
This is the same end-state reported in #10485 (closed as unreproducible, now locked — the bot's closing message says to open a new issue if it persists). We hit it on payload 3.84.1, i.e. long after the form-state overhaul (#11946) that was believed to make it unreproducible, and we have DB forensics narrowing down when and how the bad data was written.
Forensic evidence
Collection: drafts enabled (localizeStatus: true, schedulePublish: true, maxPerDoc: 50), a localized: true blocks field named layout with 4 block types, @payloadcms/db-postgres.
Version-table trace for the affected document (version_updated_by_id joined, block rows unioned per version, one locale shown):
Version
Saved (UTC)
Action
layout rows (type:_order)
v4/v5
2026-07-22 08:50
publish (locale A)
header:1
v6/v7
2026-07-22 08:52
publish (locale A)
header:1, cardGrid:3 ← gap born here
v8/v9
2026-07-23 12:28
publish (locale B)
header:1, cardGrid:3 (inherited)
Between two saves 2 minutes apart, a block add went from 1 block to rows at positions 1 and 3 — the middle row was silently dropped at write time while its neighbour kept index 3. This was not a reorder/delete; the same editing session also produced a This field requires at least 1 Rows. validation error on one of the block types (an array field with minRows: 1), which may be the row that vanished. Only one locale of the document was affected; the corruption then propagated into every subsequent version snapshot, and into the published tables on publish.
Two independent problems
Write path: the postgres adapter accepts a sparse/invalid rows array and persists non-contiguous _order values instead of rejecting the write or compacting the array. Whatever produces the undefined middle row client-side, the server persisting it turns a UI glitch into durable data corruption.
Read path: addFieldStatePromise throws on an undefined block row, which fails form-state for the whole document. A degraded render (skip the row / show an error placeholder, as requested in Block Undefined in Array of Blocks and Unable to Load Edit View for Document #10485) would keep the document editable so editors could fix it themselves.
We'd be happy to contribute a PR for (2) if maintainers agree with the skip-with-warning approach.
Note on the reproduction link: it is the repro repo from #10485 (by @58bits), which reproduces the same failure class. We cannot yet reproduce the client-side trigger on demand — matching #10485 — but the corrupt state and the resulting lock-out reproduce deterministically:
Create a blank app (pnpx create-payload-app@latest -t blank) with @payloadcms/db-postgres, drafts enabled, and a blocks field (e.g. layout) with 2+ block types. Localization is how we hit it in production but is not required for the read-path failure.
Create a document with 3 blocks in layout and publish/save it.
Simulate the sparse write our production trace shows (a middle row dropped at write time while the neighbour keeps its index) by removing the middle block row directly in the DB, leaving _order 1 and 3 — e.g. DELETE FROM <collection>_blocks_<middle_block> WHERE _parent_id = <doc_id> AND _order = 2; (do the same in the _<collection>_v_blocks_* version tables for the latest draft version).
Open the document in the admin panel.
Observed: the edit view fails to load; the server logs Block with type "undefined" was found in block data, but no block with that type is defined in the config for field with schema path <collection>.layout on every form-state request. The document is uneditable.
Expected: the write path never persists a gapped _order sequence (reject or compact), and/or the form-state builder degrades gracefully (skip the undefined row with a warning) so the document stays editable.
Which area(s) are affected?
db: postgres, area: ui
Environment Info
Production (where the corruption was written): Payload 3.84.1, Next.js 16.2.9, Node.js 22 (Docker on Kubernetes), Postgres 18 (AWS RDS), multiple locales, localized blocks field, drafts with localizeStatus.
`pnpm payload info` from the affected project:
Relevant Packages:
payload: 3.84.1
next: 16.2.9
@payloadcms/db-postgres: 3.84.1
@payloadcms/live-preview-react: 3.84.1
@payloadcms/next/utilities: 3.84.1
@payloadcms/plugin-form-builder: 3.84.1
@payloadcms/plugin-import-export: 3.84.1
@payloadcms/plugin-mcp: 3.84.1
@payloadcms/plugin-nested-docs: 3.84.1
@payloadcms/plugin-redirects: 3.84.1
@payloadcms/plugin-search: 3.84.1
@payloadcms/plugin-seo: 3.84.1
@payloadcms/richtext-lexical: 3.84.1
@payloadcms/storage-s3: 3.84.1
@payloadcms/ui/shared: 3.84.1
react: 19.2.4
react-dom: 19.2.4
Describe the Bug
A block add through the admin UI persisted a sparse blocks array to Postgres: the surviving rows kept their original array indexes (
_order1 and 3) with no row at_order2. On every subsequent read, Payload rehydrates the gap as anundefinedarray entry, and the form-state builder throws:The result is that the entire edit view for the document fails to load in the affected locale — editors are locked out of the document until the underlying rows are repaired (a draft save that happens to rewrite the array also clears it).
This is the same end-state reported in #10485 (closed as unreproducible, now locked — the bot's closing message says to open a new issue if it persists). We hit it on payload 3.84.1, i.e. long after the form-state overhaul (#11946) that was believed to make it unreproducible, and we have DB forensics narrowing down when and how the bad data was written.
Forensic evidence
Collection: drafts enabled (
localizeStatus: true,schedulePublish: true,maxPerDoc: 50), alocalized: trueblocks field namedlayoutwith 4 block types,@payloadcms/db-postgres.Version-table trace for the affected document (
version_updated_by_idjoined, block rows unioned per version, one locale shown):layoutrows (type:_order)header:1header:1, cardGrid:3← gap born hereheader:1, cardGrid:3(inherited)Between two saves 2 minutes apart, a block add went from 1 block to rows at positions 1 and 3 — the middle row was silently dropped at write time while its neighbour kept index 3. This was not a reorder/delete; the same editing session also produced a
This field requires at least 1 Rows.validation error on one of the block types (an array field withminRows: 1), which may be the row that vanished. Only one locale of the document was affected; the corruption then propagated into every subsequent version snapshot, and into the published tables on publish.Two independent problems
_ordervalues instead of rejecting the write or compacting the array. Whatever produces the undefined middle row client-side, the server persisting it turns a UI glitch into durable data corruption.addFieldStatePromisethrows on anundefinedblock row, which fails form-state for the whole document. A degraded render (skip the row / show an error placeholder, as requested in Block Undefined in Array of Blocks and Unable to Load Edit View for Document #10485) would keep the document editable so editors could fix it themselves.We'd be happy to contribute a PR for (2) if maintainers agree with the skip-with-warning approach.
Link to the code that reproduces this issue
https://github.com/infonomic/payload-block-error
Reproduction Steps
Note on the reproduction link: it is the repro repo from #10485 (by @58bits), which reproduces the same failure class. We cannot yet reproduce the client-side trigger on demand — matching #10485 — but the corrupt state and the resulting lock-out reproduce deterministically:
pnpx create-payload-app@latest -t blank) with@payloadcms/db-postgres, drafts enabled, and a blocks field (e.g.layout) with 2+ block types. Localization is how we hit it in production but is not required for the read-path failure.layoutand publish/save it._order1 and 3 — e.g.DELETE FROM <collection>_blocks_<middle_block> WHERE _parent_id = <doc_id> AND _order = 2;(do the same in the_<collection>_v_blocks_*version tables for the latest draft version).Block with type "undefined" was found in block data, but no block with that type is defined in the config for field with schema path <collection>.layouton every form-state request. The document is uneditable._ordersequence (reject or compact), and/or the form-state builder degrades gracefully (skip the undefined row with a warning) so the document stays editable.Which area(s) are affected?
db: postgres, area: ui
Environment Info