Skip to content

fix: skip empty object write for untouched localized fields in mergeLocalizedData#16649

Open
rachit367 wants to merge 1 commit into
payloadcms:mainfrom
rachit367:fix-publish-specific-locale-empty-object
Open

fix: skip empty object write for untouched localized fields in mergeLocalizedData#16649
rachit367 wants to merge 1 commit into
payloadcms:mainfrom
rachit367:fix-publish-specific-locale-empty-object

Conversation

@rachit367
Copy link
Copy Markdown

What?

Stop mergeLocalizedData from writing {} for a localized field that has no value in any locale and no incoming value.

In packages/payload/src/utilities/mergeLocalizedData.ts, the default case of the localized branch:

  • Reads existingValue from the doc and only treats it as locale data when it is a plain object (not arrays, not nullish, not other primitives).
  • Drops the previous else that unconditionally assigned existingValue (which had been defaulted to {}). The preservation path now only runs when there is real existing locale data.
  • When newValue is not a valid object and there is no existing locale data, the field is left absent on the result instead of being written as {}.

Two unit tests added under the existing simple fields group:

  • should not write an empty object when localized field has no value in any locale
  • should preserve existing locale data on a localized field when new value is undefined

Why?

Fixes #16296.

When publishSpecificLocale is used on a document where a localized field has never been written in any locale, the merge path took docWithLocales[field.name] || {} and then fell through to result[field.name] = existingValue. That wrote {} to the DB for the untouched field, so a later read with locale: 'all' returned subtitle: {} instead of the field being absent.

The repro from the issue exercises this through _community integration tests; the unit-level behavior is the same and is now covered directly in mergeLocalizedData.spec.ts.

How?

Scope is limited to the default case of the localized branch in mergeLocalizedData. Behavior in the other branches (arrays, blocks, groups, tabs) is unchanged.

Walk-through of cases in the modified branch:

  • Incoming locale object on a previously-empty field: still merges into a fresh {} and writes the new locales — unchanged.
  • Incoming locale object on a field that already has other locales: still merges over the existing locales — unchanged.
  • No incoming value, existing locales present: still preserved.
  • No incoming value, no existing locales: previously wrote {}, now leaves the field absent.
  • Child of a localized parent: still replaces with the new value — unchanged.

No other call sites needed to change. mergeLocalizedData always returns a plain object whose field.name may or may not be present; callers already handle the absent case the same way they would have handled undefined.

@rachit367 rachit367 changed the title fix(payload): skip empty object write for untouched localized fields in mergeLocalizedData fix: skip empty object write for untouched localized fields in mergeLocalizedData May 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

publishSpecificLocale writes {} for localized fields that have never been saved in any locale

1 participant