payloadcms / payloadcms/payload

plugin-seo & ui: PreviewField throws "circular structure to JSON"

Open
#16,786 0 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

plugin: seo stale status: needs-triage v3
Dominant language
TypeScript
Stars
44.8k
Forks
4.2k
Avg merge
2d 21h
Merged PRs (30d)
53

Description

Describe the Bug

On the SEO tab of a document that contains an array field with a custom RowLabel component and at least one row with a populated relationship, Payload throws:

  TypeError: Converting circular structure to JSON
      --> starting at object with constructor 'BasePayload'
      |     property 'db' -> object with constructor 'Object'
      --- property 'payload' closes the circle

It throws inside PreviewComponent's useEffect while building the body for POST /api/plugin-seo/generate-url. MetaTitleField's Auto-generate button does the same
thing against /api/plugin-seo/generate-title.

reduceToSerializableFields in @payloadcms/ui calls a shallow sanitizeField helper that strips customComponents and validate only from the top-level of each field entry. Array form state has the same keys inside rows[i], and those still hold the rendered RowLabel tree.

Link to the code that reproduces this issue

https://github.com/codeplott/payloadcms-rowlabel-plugin-seo

Reproduction Steps

Clone: https://github.com/codeplott/payloadcms-rowlabel-plugin-seo

  1. Create a page, give it a title and slug, save.
  2. Add one entry to the links array, set label, pick the page itself (or any other page) for reference, save.
  3. Reload the edit view.
  4. The runtime error overlay shows Converting circular structure to JSON ... BasePayload ... db ... payload.
  5. The SEO Preview URL stays at https://... instead of what generateURL would produce. Clicking the MetaTitle "Auto-generate" button throws the same error.
Which area(s) are affected?

plugin: seo

Environment Info
Binaries:
    Node: 24.16.0
    npm: 11.15.0
    pnpm: 10.33.4
  Relevant Packages:
    payload: 3.85.0
    next: 16.2.6
    @payloadcms/db-mongodb: 3.85.0
    @payloadcms/graphql: 3.85.0
    @payloadcms/next/utilities: 3.85.0
    @payloadcms/plugin-seo: 3.85.0
    @payloadcms/richtext-lexical: 3.85.0
    @payloadcms/translations: 3.85.0
    @payloadcms/ui/shared: 3.85.0
    react: 19.2.6
    react-dom: 19.2.6
  Operating System:
    Platform: darwin
    Arch: arm64

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 reproducing the linked project, then trace reduceToSerializableFields and its sanitizeField helper in @payloadcms/ui from PreviewComponent and MetaTitleField. Verify that array rows containing a custom RowLabel and populated relationship can be serialized for both plugin-seo requests without the circular-structure error, and that the generated URL/title actions complete.

Written by the indexing model from the issue text.

Assessment

Tech stack
nextjs, react, typescript
Domain
api, frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
62/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.