payloadcms/payload · warning · ValidationError
The following field is invalid: ${name}
Error message
The following field is invalid: ${name} What it means
Thrown by the `generateSlug` beforeChange hook as a `ValidationError` when an explicitly provided slug value collides with an existing document's slug. Unlike generated slugs (which auto-dedupe with a suffix), an explicit user-supplied slug is checked for uniqueness and rejected if taken, surfacing a localized 'value must be unique' message on the field. This keeps user-chosen slugs stable rather than silently mutating them.
Source
Thrown at packages/payload/src/fields/baseFields/slug/generateSlug.ts:84
// Unchanged from what's stored — already unique, so skip the collision query. Autosave
// resends the current slug on every tick; without this each tick runs a needless read.
if (slugified === storedSlug) {
return storedSlug
}
if (
collection &&
(await fieldValueExists({
id: originalDoc?.id,
collection: collection.slug,
draftsEnabled: hasDraftsEnabled(collection),
field: name,
locale,
req,
value: slugified,
}))
) {
throw new ValidationError(
{ errors: [{ message: req.t('error:valueMustBeUnique'), path: name }] },
req.t,
)
}
return slugified
}
}
// On update, preserve a slug that is already set — only fill it while empty.
if (operation !== 'create' && storedSlugHasValue) {
return storedSlug
}
// Derive an empty slug from its source, when present.
// Dedupe so two documents don't both claim it if they have the same source value.
// Globals have no collection to dedupe against.
const source = useAsSlug ? data?.[useAsSlug] : undefinedView on GitHub (pinned to 00c58b35c0)
Solutions
- Generate the slug server-side and let Payload auto-dedupe (omit the explicit `slug` value).
- Before saving, check uniqueness: `payload.find({ collection, where: { slug: { equals } }, limit: 1 })`.
- Catch the `ValidationError` and prompt the user to pick another slug.
Example fix
// before
await payload.create({ collection: 'posts', data: { slug: 'hello', title: 'Hi' } }) // may collide
// after
const slug = await getUniqueSlug('hello') // or omit slug to let Payload generate
await payload.create({ collection: 'posts', data: { slug, title: 'Hi' } }) Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check slug uniqueness before create/update
const { totalDocs } = await payload.count({
collection,
where: { and: [{ slug: { equals: proposedSlug } }, { id: { not_equals: currentId ?? 0 } }] },
req,
})
if (totalDocs > 0) throw new Error(`Slug '${proposedSlug}' is already in use`) Try / catch
try {
await payload.create({ collection, data })
} catch (err) {
if (err instanceof ValidationError && err.data?.errors?.some((e) => /unique/i.test(e.message))) {
// prompt user for a different slug, or auto-generate one
}
throw err
} Prevention
- Omit the slug to let Payload generate and auto-dedupe it.
- Validate uniqueness before save for user-typed slugs.
- Catch ValidationError at the form boundary and show a field error.
When it happens
Trigger: Creating/updating a doc with `data.slug = 'taken'` when another doc already has that slug; two docs sharing a source field that produces the same explicit slug; localized slug colliding within the same locale.
Common situations: Admin UI where a user types a slug already in use; import scripts assigning duplicate slugs; renaming a doc's title whose derived slug clashes with an existing one when the slug is explicitly set.
Related errors
- Value must be unique
- Value must be unique
- The hierarchy title field "${titleFieldName}" was not found.
- Invalid template given
- Invalid database type given. Valid types are: ${Object.value
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/3d4588fb6f8e0f25.
Report an issue: GitHub.