payloadcms/payload · error · ValidationError

validation:required

Error message

validation:required

What it means

A `ValidationError` (400) thrown during login when the collection cannot log in with email (`!canLoginWithEmail`) and no username was supplied. With `loginWithUsername` configured such that email login is disabled, the username is the only accepted identifier; omitting it fails the 'required' validation on the `username` field. The message is the localized `validation:required`.

Source

Thrown at packages/payload/src/auth/operations/login.ts:125

  // /////////////////////////////////////
  // Login
  // /////////////////////////////////////

  const { email: unsanitizedEmail, password } = data
  const loginWithUsername = collectionConfig.auth.loginWithUsername

  const sanitizedEmail =
    typeof unsanitizedEmail === 'string' ? unsanitizedEmail.toLowerCase().trim() : null
  const sanitizedUsername =
    'username' in data && typeof data?.username === 'string'
      ? data.username.toLowerCase().trim()
      : null

  const { canLoginWithEmail, canLoginWithUsername } = getLoginOptions(loginWithUsername)

  // cannot login with email, did not provide username
  if (!canLoginWithEmail && !sanitizedUsername) {
    throw new ValidationError({
      collection: collectionConfig.slug,
      errors: [{ message: req.i18n.t('validation:required'), path: 'username' }],
    })
  }

  // cannot login with username, did not provide email
  if (!canLoginWithUsername && !sanitizedEmail) {
    throw new ValidationError({
      collection: collectionConfig.slug,
      errors: [{ message: req.i18n.t('validation:required'), path: 'email' }],
    })
  }

  // can login with either email or username, did not provide either
  if (!sanitizedUsername && !sanitizedEmail) {
    throw new ValidationError({
      collection: collectionConfig.slug,
      errors: [

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Send a `username` in the login data for username-only collections.
  2. Align the collection config (`allowEmailLogin`) with what the login form collects.
  3. Make the client form adapt: collect username when email login is disabled.

Example fix

// before — username-only collection, sending email
await payload.login({ collection: 'users', data: { email, password } })

// after — send username
await payload.login({ collection: 'users', data: { username, password } })
Defensive patterns

Strategy: validation

Validate before calling

const loginOpts = getLoginOptions(collection.config.auth.loginWithUsername)
if (!loginOpts.canLoginWithEmail && !data.username) throw new Error('Username required')

Try / catch

try {
  await payload.login({ collection, data })
} catch (e) {
  if (e instanceof ValidationError && e.data?.errors?.some(er => er.path === 'username')) {
    // collect and send a username
  }
  throw e
}

Prevention

When it happens

Trigger: Collection configured `auth.loginWithUsername: { allowEmailLogin: false }` and the login request sends only an email (or nothing); `data: { email, password }` against a username-only collection.

Common situations: Frontend login form built for email but the collection is username-only; mismatched collection config and client expectations; enabling `loginWithUsername` without updating the login UI.

Related errors


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