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] : undefined

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Generate the slug server-side and let Payload auto-dedupe (omit the explicit `slug` value).
  2. Before saving, check uniqueness: `payload.find({ collection, where: { slug: { equals } }, limit: 1 })`.
  3. 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

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


AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12). Data as JSON: /api/errors/3d4588fb6f8e0f25. Report an issue: GitHub.