payloadcms / payloadcms/payload

Strange crash with server actions on admin interface custom editor + Feature suggestion

Open
#15,489 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area: core stale
Dominant language
TypeScript
Stars
44.8k
Forks
4.2k
Avg merge
2d 21h
Merged PRs (30d)
53

Description

Describe the Bug

Using custom way to manage links generate an issue in the admin panel for some reasons.

I'm managing links that way, so typings are perfectly pinned like this, which is better for types inference as this is a discriminated union.

export interface PageLink {
  page: number | Page;
  newTab?: boolean | null;
  id?: string | null;
  blockName?: string | null;
  blockType: 'page-link';
}

export interface CustomLink {
  url: string;
  newTab?: boolean | null;
  id?: string | null;
  blockName?: string | null;
  blockType: 'custom-link';
}

Produce on admin :

Generating import map
Writing import map to /Users/screamz/dev-workspace/pro/repro/src/app/(payload)/admin/importMap.js
 ⨯ Error: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server". Or maybe you meant to call this function rather than return it.
  {name: "page", type: ..., relationTo: ..., required: ..., label: ..., validate: function, hooks: ..., access: ..., admin: ...}
                                                                                  ^^^^^^^^
    at stringify (<anonymo

I'm using the same pattern outside of lexical editor, works finely.

Quick side note for improvement + Feature suggestion

Could be nice to specify that the block type doesn't wait for array. But a single block. (maybe have block and block-array type ?
Currently I'm using maxRows: 1, but the generated type remains an array, so i have to write data[0] to get the element each time

Single block

export const LinkField = {
  name: "link",
- type: "blocks",
+ type: "block"
  label: "Link",
  required: true,
- maxRows: 1,
  blockReferences: ["page-link", "custom-link"],
  blocks: [],
} as const satisfies Field;

Multi block

export const LinkField = {
  name: "link",
- type: "blocks",
+ type: "block-array" // or block-collection
  label: "Link",
  required: true,
  maxRows: 1,
  blockReferences: ["page-link", "custom-link"],
  blocks: [],
} as const satisfies Field;
Link to the code that reproduces this issue

https://github.com/ScreamZ/repro-payload-bug

Reproduction Steps

Run the application, head to admin interface and create a new page. When displaying the rich text editor, crash.

Which area(s) are affected?

area: core

Environment Info
Binaries:
  Node: 25.5.0
  npm: 11.8.0
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  payload: 3.74.0
  next: 15.4.11
  @payloadcms/db-sqlite: 3.74.0
  @payloadcms/drizzle: 3.74.0
  @payloadcms/graphql: 3.74.0
  @payloadcms/next/utilities: 3.74.0
  @payloadcms/richtext-lexical: 3.74.0
  @payloadcms/translations: 3.74.0
  @payloadcms/ui/shared: 3.74.0
  react: 19.2.1
  react-dom: 19.2.1
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.2.0: Tue Nov 18 21:09:40 PST 2025; root:xnu-12377.61.12~1/RELEASE_ARM64_T6000
  Available memory (MB): 32768
  Available CPU cores: 10

Contributor guide

Open the contributing guide

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.

Research direction

Start by running the linked repro application, opening the admin interface, and creating a page to trigger the rich text editor crash. Trace the server-action error around the generated admin import map and the custom link field, then verify that the admin page loads without the reported Client Components error. The proposed single-block type is a separate feature suggestion and needs clarification.

Written by the indexing model from the issue text.

Assessment

Tech stack
next.js, react, typescript
Domain
backend, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.