payloadcms / payloadcms/payload
Fields with `admin.condition` are silently hidden in bulk edit
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 44.8k
- Forks
- 4.2k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 53
Description
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
https://github.com/user-attachments/assets/147c2d29-9c65-484c-9151-35dc22400fd2
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 false → passesCondition = 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:
- Exposing
skipConditionChecksinBuildFormStateArgs(packages/payload/src/admin/forms/Form.ts) - Passing it through
buildFormState→iterateFields - Setting it in both
getFormStatecalls inpackages/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
- Clone reproduction repo (
bulk-edit-condition-reprobranch) - Start dev server
- 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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/ui/src/elements/EditMany/DrawerContent.tsx and inspect both getFormState calls used by onChange and onFieldSelect. Trace skipConditionChecks through packages/payload/src/admin/forms/Form.ts, buildFormState, and iterateFields.ts. Reproduce with the linked bulk-edit-condition example; done means fields with admin.condition render correctly in bulk edit without requiring dependent fields to be selected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 65/100