{"record":{"id":"b64f0afde82ce3e8","repo":"payloadcms/payload","slug":"email-is-required","errorCode":null,"errorMessage":"Email is required.","messagePattern":"Email is required\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/payload/src/auth/serverFunctions/login.ts","lineNumber":65,"sourceCode":"  if (!authConfig) {\n    throw new Error(`No auth config found for collection: ${collection}`)\n  }\n\n  const loginWithUsername = authConfig.loginWithUsername ?? false\n\n  if (loginWithUsername) {\n    if (loginWithUsername.allowEmailLogin) {\n      if (!email && !username) {\n        throw new Error('Email or username is required.')\n      }\n    } else {\n      if (!username) {\n        throw new Error('Username is required.')\n      }\n    }\n  } else {\n    if (!email) {\n      throw new Error('Email is required.')\n    }\n  }\n\n  let loginData\n\n  if (loginWithUsername) {\n    loginData = username ? { password, username } : { email, password }\n  } else {\n    loginData = { email, password }\n  }\n\n  const collectionConfig = payload.collections[collection]!\n\n  const { cookie, result } = await loginWithCookie({\n    collection: collectionConfig,\n    data: loginData as Parameters<typeof loginWithCookie>[0]['data'],\n    overrideAccess: true,\n    req: await createLocalReq({}, payload),","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/payload/src/auth/serverFunctions/login.ts#L47-L83","documentation":"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.","triggerScenarios":"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.","commonSituations":"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`.","solutions":["Provide a non-empty `email` value in the `login` call.","If you intend username login, enable `auth.loginWithUsername` on the collection."],"exampleFix":"// before\nawait login({ collection: 'users', config, password, serverAdapter })\n// after\nawait login({ collection: 'users', config, email: form.email, password, serverAdapter })","handlingStrategy":"validation","validationCode":"function validateEmailLogin(args) {\n  if (!args.loginWithUsername && !args.email?.trim()) {\n    return { ok: false, message: 'Email is required.' }\n  }\n  return { ok: true }\n}","typeGuard":"function hasEmail(args): args is { email: string } {\n  return typeof args?.email === 'string' && args.email.trim().length > 0\n}","tryCatchPattern":null,"preventionTips":["Validate a non-empty email on the client before calling `login`.","Keep the collection's auth strategy aligned with the form's fields."],"tags":["auth","login","validation","email"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}