Philipp Schneider a62cdc89d8 fix(ui): blockType ignored when merging server form state (#12207)
In this case, the `blockType` property is created on the server, but -
prior to this fix - was discarded on the client in
[`fieldReducer.ts`](https://github.com/payloadcms/payload/blob/main/packages/ui/src/forms/Form/fieldReducer.ts#L186-L198)
via
[`mergerServerFormState.ts`](b9832f40e4/packages/ui/src/forms/Form/mergeServerFormState.ts (L29-L31)),
because the field's path neither existed in the client's form state, nor
was it marked as `addedByServer`.

This caused later calls to POST requests to form state to send without
the `blockType` key for block rows, which in turn caused
`addFieldStatePromise.ts` to throw the following error:

```
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 ${schemaPath}.
```

This prevented the client side form state update from completing, and if
the form state was saved, broke the document.

This is a follow-up to #12131, which treated the symptom, but not the
cause. The original issue seems to have been introduced in
https://github.com/payloadcms/payload/releases/tag/v3.34.0. It's unclear
to me whether this issue is connected to block E2E tests having been
disabled in the same release in
https://github.com/payloadcms/payload/pull/11988.

## How to reproduce

### Collection configuration

```ts
const RICH_TEXT_BLOCK_TYPE = 'richTextBlockType'

const RichTextBlock: Block = {
  slug: RICH_TEXT_BLOCK_TYPE,
  interfaceName: 'RichTextBlock',
  fields: [
    {
      name: 'richTextBlockField',
      label: 'Rich Text Field in Block Field',
      type: 'richText',
      editor: lexicalEditor({}),
      required: true,
    },
  ],
}

const MyCollection: CollectionConfig = {
  slug: 'my-collection-slug,
  fields: [
    {
      name: 'arrayField',
      label: 'Array Field',
      type: 'array',
      fields: [
        {
          name: 'blockField',
          type: 'blocks',
          blocks: [RichTextBlock],
          required: true,
        },
      ],
    },
  ]
}

export default MyCollection
```

### Steps

- Press "Add Array Field"
   -->  1st block with rich text is added
- Press "Add Array Field" a 2nd time

### Result
- 🛑 2nd block is indefinitely in loading state (side-note: the form UI
should preferably explicitly indicate the error).
- 🛑 If saving the document, it is corrupted and will only show a blank
page (also not indicating any error).

Client side:

<img width="1268" alt="Untitled"
src="https://github.com/user-attachments/assets/4b32fdeb-af76-41e2-9181-d2dbd686618a"
/>

API error:

<img width="1272" alt="image"
src="https://github.com/user-attachments/assets/35dc65f7-88ac-4397-b8d4-353bcf6a4bfd"
/>

Client side, when saving and re-opening document (API error of `GET
/admin/collections/${myCollection}/${documentId}` is the same (arguably
the HTTP response status code shouldn't be `200`)):

<img width="1281" alt="image"
src="https://github.com/user-attachments/assets/2e916eb5-6f10-4e82-9b84-1dc41db21d47"
/>

### Result after fix
- `blockType` is sent from the client to the server.
-  2nd block with rich text is added.
-  Document does not break when saving & re-opening.

<img width="1277" alt="Untitled"
src="https://github.com/user-attachments/assets/84d0c88b-64b2-48c4-864d-610d524ac8fc"
/>

---------

Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
2025-05-02 10:18:11 -04:00
2024-08-16 15:22:56 -04:00
2024-08-13 12:54:33 -04:00
2020-08-06 08:49:40 -04:00
2024-08-29 23:29:40 -04:00
2025-04-30 14:52:46 -04:00
2022-03-24 21:14:17 -04:00
2025-03-05 19:14:35 +00:00

Payload headless CMS Admin panel built with React

GitHub Workflow Status   Discord   npm   npm   npm   Payload Twitter


Explore the Docs · Community Help · Roadmap · View G2 Reviews


Important

🎉 We've released 3.0! Star this repo or keep an eye on it to follow along.

Payload is the first-ever Next.js native CMS that can install directly in your existing /app folder. It's the start of a new era for headless CMS.

Benefits over a regular CMS

  • Deploy anywhere, including serverless on Vercel for free
  • Combine your front+backend in the same /app folder if you want
  • Don't sign up for yet another SaaS - Payload is open source
  • Query your database in React Server Components
  • Both admin and backend are 100% extensible
  • No vendor lock-in
  • Never touch ancient WP code again
  • Build faster, never hit a roadblock

Quickstart

Before beginning to work with Payload, make sure you have all of the required software.

pnpx create-payload-app@latest

If you're new to Payload, you should start with the website template (pnpx create-payload-app@latest -t website). It shows how to do everything - including custom Rich Text blocks, on-demand revalidation, live preview, and more. It comes with a frontend built with Tailwind all in one /app folder.

One-click templates

Jumpstart your next project by starting with a pre-made template. These are production-ready, end-to-end solutions designed to get you to market as fast as possible.

🌐 Website

Build any kind of website, blog, or portfolio from small to enterprise. Comes with a fully functional front-end built with RSCs and Tailwind.

We're constantly adding more templates to our Templates Directory. If you maintain your own template, consider adding the payload-template topic to your GitHub repository for others to find.

Features

Request Feature

🗒️ Documentation

Check out the Payload website to find in-depth documentation for everything that Payload offers.

Migrating from v2 to v3? Check out the 3.0 Migration Guide on how to do it.

🙋 Contributing

If you want to add contributions to this repository, please follow the instructions in contributing.md.

📚 Examples

The Examples Directory is a great resource for learning how to setup Payload in a variety of different ways, but you can also find great examples in our blog and throughout our social media.

If you'd like to run the examples, you can use create-payload-app to create a project from one:

npx create-payload-app --example example_name

You can see more examples at:

🔌 Plugins

Payload is highly extensible and allows you to install or distribute plugins that add or remove functionality. There are both officially-supported and community-supported plugins available. If you maintain your own plugin, consider adding the payload-plugin topic to your GitHub repository for others to find.

🚨 Need help?

There are lots of good conversations and resources in our Github Discussions board and our Discord Server. If you're struggling with something, chances are, someone's already solved what you're up against. 👇

Like what we're doing? Give us a star

payload-github-star

👏 Thanks to all our contributors

Description
Payload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a headless CMS or for building powerful applications.
Readme 269 MiB
Languages
TypeScript 95.8%
SCSS 2.9%
JavaScript 1.1%
Dockerfile 0.1%
CSS 0.1%