Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Required Lexical field accepts two empty paragraphs

Open Beginner friendly
#19,222 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@lazerg is already working on this.

Since Oct 30, 2026.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
react, typescript
Domain
backend, testing

Research direction

Start with packages/richtext-lexical/src/validate/hasText.ts and the required check in packages/richtext-lexical/src/validate/index.ts; inspect tests for hasText and required rich text validation. Check how empty paragraphs are detected while preserving content without text, such as uploads and blocks. Done when multiple empty paragraphs fail required validation and those other content types still pass.

Written by the indexing model from the issue text.

Description

Bug

Describe the Bug

A richText field with required: true and the default lexicalEditor() accepts an editor state that holds only two empty paragraphs. One Enter in an empty editor creates that state, so a user can save a required field with no content.

hasText treats the state as empty only when the root has no children, or when it has exactly one paragraph with no children or one empty text node. With two empty paragraphs the single-paragraph check does not apply, and hasText returns true. The required check relies on hasText.

#6435 fixed a similar case, content that was removed by hand. The case with several empty paragraphs remains. It behaves the same in 3.91.0, 3.92.1, 4.0.0-beta.0 to beta.6 and on main (09dab7ea).

Expected: a state that holds only empty paragraphs fails required, as one empty paragraph does today. Content without text, such as an upload or a block, should still pass.

Link to the code that reproduces this issue

https://github.com/woerndl/payload-lexical-required-empty-paragraphs

Reproduction Steps

  1. Clone the reproduction, copy .env.example to .env and set DATABASE_URL and PAYLOAD_SECRET.
  2. pnpm install, pnpm generate:importmap, pnpm dev.
  3. Create the first user, open Posts and click Create New.
  4. Click Save without touching Body. The save fails: "This field is required."
  5. Click into Body, press Enter once, click Save. The post is created.

The stored value:

{
  "root": {
    "type": "root",
    "children": [
      { "type": "paragraph", "children": [], "direction": null, "format": "", "indent": 0, "textFormat": 0, "textStyle": "", "version": 1 },
      { "type": "paragraph", "children": [], "direction": null, "format": "", "indent": 0, "textFormat": 0, "textStyle": "", "version": 1 }
    ],
    "direction": null, "format": "", "indent": 0, "version": 1
  }
}

The Local API shows the same (pnpm payload run src/repro.ts):

one empty paragraph: rejected (The following field is invalid: Body)
two empty paragraphs: saved <id>

Which area(s) are affected?

plugin: richtext-lexical

Environment Info

Binaries:
  Node: 22.23.4
  pnpm: 10.34.7
Relevant Packages:
  payload: 3.91.0
  next: 16.3.3
  @payloadcms/db-mongodb: 3.91.0
  @payloadcms/richtext-lexical: 3.91.0
  @payloadcms/ui/shared: 3.91.0
  react: 19.2.6
Operating System:
  Platform: darwin
  Arch: arm64

Reproduced in the admin and through the Local API on 3.91.0. For the other versions above, the hasText function from each published package was run on the same states.

Dominant language
TypeScript
Stars
45.5k
Forks
4.3k
Avg merge
1d 15h
Merged PRs (30d)
302

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from payloadcms/payload

All issues in payloadcms/payload

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.