payloadcms / payloadcms/payload

traverseFields silently skips localized group/tab children when walking locale-resolved documents

Open
#18,217 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area: core Bug invalid-reproduction 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

traverseFields accepts a document as ref and walks it against the field schema, which makes it the natural utility for anything that needs "every field value in this document, with its schema". But it assumes ref is in the database shape, where a localized field holds a map of locale → value. A document fetched through the public API (payload.find({ locale }), payload.findByID({ locale }), payload.findGlobal({ locale })) is in the resolved shape, where a localized field holds the value for that one locale.

For localized group and tab fields the code iterates for (const key in currentRef) treating each key as a locale, recurses with ref set to the value rather than an object of values, hits the if (!ref || typeof ref !== 'object') return check, and stops, which causes the entire subtree under the localized group is skipped.

Link to the code that reproduces this issue

https://stackblitz.com/edit/traverse-field-repro

Reproduction Steps

Run npm run repro

Actual output:

title (text)
legal (group)
links (array)
links.label (text)      ← the localized array works

Expected output: the same, plus legal.notice (text). It is the only field in the document
that is never visited, and nothing signals that it was skipped.

Which area(s) are affected?

area: core

Environment Info
Binaries:
  Node: 22.14.0
  npm: 10.9.2
  Yarn: 4.17.0
  pnpm: N/A
Relevant Packages:
  payload: 3.89.0
  next: 16.3.5
  @payloadcms/db-mongodb: 3.89.0
  @payloadcms/db-sqlite: 3.89.0
  @payloadcms/drizzle: 3.89.0
  @payloadcms/graphql: 3.89.0
  @payloadcms/live-preview: 3.89.0
  @payloadcms/live-preview-react: 3.89.0
  @payloadcms/next/utilities: 3.89.0
  @payloadcms/plugin-cloud-storage: 3.89.0
  @payloadcms/richtext-lexical: 3.89.0
  @payloadcms/storage-s3: 3.89.0
  @payloadcms/translations: 3.89.0
  @payloadcms/ui/shared: 3.89.0
  react: 19.3.0
  react-dom: 19.3.0
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.6.0: Fri Jul 31 19:16:36 PDT 2026; root:xnu-12377.161.14~5/RELEASE_ARM64_T6030
  Available memory (MB): 18432
  Available CPU cores: 11

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

Run npm run repro from the linked reproduction, then search the repository for traverseFields and compare its handling of database-shaped and locale-resolved documents. Trace the localized group and tab cases, and add coverage showing that legal.notice is visited while the existing title, legal, links, and links.label output remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.