payloadcms/payload · error · Error

Email is required.

Error message

Email is required.

What it means

Thrown by the `login` server function when the target collection does NOT have `loginWithUsername` enabled and no `email` was supplied. This is the default email-based auth input guard: the collection expects email login, so an empty email is rejected before credentials are checked.

Source

Thrown at packages/payload/src/auth/serverFunctions/login.ts:65

  if (!authConfig) {
    throw new Error(`No auth config found for collection: ${collection}`)
  }

  const loginWithUsername = authConfig.loginWithUsername ?? false

  if (loginWithUsername) {
    if (loginWithUsername.allowEmailLogin) {
      if (!email && !username) {
        throw new Error('Email or username is required.')
      }
    } else {
      if (!username) {
        throw new Error('Username is required.')
      }
    }
  } else {
    if (!email) {
      throw new Error('Email is required.')
    }
  }

  let loginData

  if (loginWithUsername) {
    loginData = username ? { password, username } : { email, password }
  } else {
    loginData = { email, password }
  }

  const collectionConfig = payload.collections[collection]!

  const { cookie, result } = await loginWithCookie({
    collection: collectionConfig,
    data: loginData as Parameters<typeof loginWithCookie>[0]['data'],
    overrideAccess: true,
    req: await createLocalReq({}, payload),

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Provide a non-empty `email` value in the `login` call.
  2. If you intend username login, enable `auth.loginWithUsername` on the collection.

Example fix

// before
await login({ collection: 'users', config, password, serverAdapter })
// after
await login({ collection: 'users', config, email: form.email, password, serverAdapter })
Defensive patterns

Strategy: validation

Validate before calling

function validateEmailLogin(args) {
  if (!args.loginWithUsername && !args.email?.trim()) {
    return { ok: false, message: 'Email is required.' }
  }
  return { ok: true }
}

Type guard

function hasEmail(args): args is { email: string } {
  return typeof args?.email === 'string' && args.email.trim().length > 0
}

Prevention

When it happens

Trigger: Calling `login({ collection, config, password, serverAdapter })` without `email` against a collection whose `auth.loginWithUsername` is undefined/false. Empty-string email is also falsy and triggers it.

Common situations: Form submitting an empty email field; adapter not forwarding the email param; a collection migrated from username-login to email-login while the client still sends `username`.

Related errors


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