Describe the Bug
A field with unique: true and required: true always gets a non-sparse unique MongoDB index. Schema builder doesn't account for admin.condition which techincally makes this field conditionally required.
https://github.com/payloadcms/payload/blob/main/packages/db-mongodb/src/models/buildSchema.ts#L84
if (
schema.unique &&
(fieldShouldBeLocalized({ field, parentIsLocalized }) ||
draftsEnabled ||
(fieldAffectsData(field) &&
field.type !== 'group' &&
field.type !== 'tab' &&
field.required !== true)) // ← only checks static required property
) {
schema.sparse = true
}
The condition checks field.required !== true — the static property on the field definition. It does not account for admin.condition.
Proposed fix
In formatBaseSchema, treat a field as effectively optional for index purposes when required: true is combined with admin.condition:
// Before
field.required !== true
// After
field.required !== true || !!field.admin?.condition
This ensures that when a field is only conditionally required, a sparse unique index is created so that null values (from documents where the condition is false) are excluded from the uniqueness constraint.
I'm not sure about other db adapters.
Link to the code that reproduces this issue
https://github.com/payloadcms/payload/blob/main/packages/db-mongodb/src/models/buildSchema.ts#L84
Reproduction Steps
// Collection field definition
{
name: 'slug',
type: 'text',
unique: true,
required: true,
admin: {
condition: (data) => data.type === 'page', // only required for pages
},
}
- Create a document where
type !== 'page' — slug is null.
- Create a second document where
type !== 'page' — slug is null again.
- MongoDB throws a unique constraint violation because the index is non-sparse and
null is treated as a duplicate value.
Which area(s) are affected?
area: core, db: mongodb
Environment Info
Binaries:
Node: 22.16.0
npm: 10.9.2
Yarn: N/A
pnpm: 10.14.0
Relevant Packages:
payload: 3.82.1
next: 16.2.3
@payloadcms/db-mongodb: 3.82.1
@payloadcms/email-nodemailer: 3.82.1
@payloadcms/graphql: 3.82.1
@payloadcms/live-preview: 3.82.1
@payloadcms/live-preview-react: 3.82.1
@payloadcms/next/utilities: 3.82.1
@payloadcms/plugin-nested-docs: 3.82.1
@payloadcms/plugin-search: 3.82.1
@payloadcms/plugin-seo: 3.82.1
@payloadcms/richtext-lexical: 3.82.1
@payloadcms/translations: 3.82.1
@payloadcms/ui/shared: 3.82.1
react: 19.2.3
react-dom: 19.2.3
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
Describe the Bug
A field with
unique: trueandrequired: truealways gets a non-sparse unique MongoDB index. Schema builder doesn't account foradmin.conditionwhich techincally makes this field conditionally required.https://github.com/payloadcms/payload/blob/main/packages/db-mongodb/src/models/buildSchema.ts#L84
The condition checks
field.required !== true— the static property on the field definition. It does not account foradmin.condition.Proposed fix
In
formatBaseSchema, treat a field as effectively optional for index purposes whenrequired: trueis combined withadmin.condition:This ensures that when a field is only conditionally required, a sparse unique index is created so that
nullvalues (from documents where the condition is false) are excluded from the uniqueness constraint.I'm not sure about other db adapters.
Link to the code that reproduces this issue
https://github.com/payloadcms/payload/blob/main/packages/db-mongodb/src/models/buildSchema.ts#L84
Reproduction Steps
type !== 'page'—slugisnull.type !== 'page'—slugisnullagain.nullis treated as a duplicate value.Which area(s) are affected?
area: core, db: mongodb
Environment Info