Skip to content

Fields with admin.condition are silently hidden in bulk edit #16336

@VeiaG

Description

@VeiaG

Describe the Bug

When a field has admin.condition defined, it appears in the Edit dropdown inside the bulk edit drawer — but after selecting it, the field is not rendered. No error or warning is shown. From the user's perspective, bulk edit simply doesn't work for that field.

There is a partial workaround on the user side: if the field that the condition depends on is also selected in the bulk edit drawer, siblingData gets populated and the condition evaluates correctly. However, this forces the user to always edit the dependent field together — which is poor UX — and may cause unintended side effects by updating a field that the user didn't intend to change.

Video showcasing this issue

Kapture.2026-04-21.at.20.39.37.mp4

Root cause

EditManyDrawerContent initializes DocumentInfoProvider with initialData: {}, so when getFormState builds the form state, siblingData is always {}.

In iterateFields.ts, the condition is evaluated as:

passesCondition = Boolean(
  field.admin.condition(fullData || {}, data || {}, { ... })
)

Since siblingData is {}, any condition that checks sibling field values evaluates to falsepassesCondition = false → the field is not rendered.

reduceFieldOptions (which populates the FieldSelect dropdown) does not check admin.condition, so the field still appears in the dropdown — making the issue invisible until you actually try to use it.

Workarounds

It is technically possible to work around this for individual fields by explicitly handling the undefined case:

For a required select/type field:

// instead of:
condition: (_, siblingData) => siblingData?.type === 'show'

// use:
condition: (_, siblingData) => !siblingData?.type || siblingData?.type === 'show'

Works because type is always explicitly set in real documents, so !siblingData?.type is only ever true in the bulk edit context.

For a boolean/checkbox field:

// instead of:
condition: (_, siblingData) => siblingData?.isEnabled === true

// use:
condition: (_, siblingData) => !(siblingData?.isEnabled === false)

Works because !(undefined === false)true in bulk edit, while still correctly evaluating false when isEnabled is explicitly unchecked.

These workarounds become increasingly fragile as conditions grow in complexity. A condition combining multiple fields:

condition: (_, siblingData) =>
  siblingData?.type === 'premium' &&
  siblingData?.isEnabled === true &&
  siblingData?.tier !== 'basic'

...requires handling undefined for every operand separately, in a way that passes in bulk edit but doesn't break normal form behavior. The result is obscure code that leaks an internal implementation detail (siblingData = {} in bulk edit) into application-level field definitions — something developers shouldn't need to know about.

Expected behavior

admin.condition has no meaningful value in bulk edit context — there is no single document, so sibling field values don't exist. Conditions should be skipped entirely when building form state for bulk edit.

The minimal fix would be to pass skipConditionChecks: true in both getFormState calls inside EditManyDrawerContent (onChange and onFieldSelect). This would require:

  1. Exposing skipConditionChecks in BuildFormStateArgs (packages/payload/src/admin/forms/Form.ts)
  2. Passing it through buildFormStateiterateFields
  3. Setting it in both getFormState calls in packages/ui/src/elements/EditMany/DrawerContent.tsx

Link to the code that reproduces this issue

https://github.com/VeiaG/payload-3-reproductions/tree/bulk-edit-condition-repro

Reproduction Steps

  1. Clone reproduction repo (bulk-edit-condition-repro branch)
  2. Start dev server
  3. Try to bulk edit in bulk-edit-condition.

Which area(s) are affected?

area: core, area: ui

Environment Info

Binaries:
  Node: 22.16.0
  npm: 10.9.2
  Yarn: N/A
  pnpm: 10.19.0
Relevant Packages:
  payload: 3.83.0
  next: 15.4.7
  @payloadcms/db-sqlite: 3.83.0
  @payloadcms/drizzle: 3.83.0
  @payloadcms/email-nodemailer: 3.83.0
  @payloadcms/graphql: 3.83.0
  @payloadcms/live-preview: 3.83.0
  @payloadcms/live-preview-react: 3.83.0
  @payloadcms/next/utilities: 3.83.0
  @payloadcms/payload-cloud: 3.83.0
  @payloadcms/plugin-nested-docs: 3.83.0
  @payloadcms/richtext-lexical: 3.83.0
  @payloadcms/translations: 3.83.0
  @payloadcms/ui/shared: 3.83.0
  react: 19.2.0
  react-dom: 19.2.0
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): 16384
  Available CPU cores: 10

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions