{"record":{"id":"9987b3a0510dace5","repo":"payloadcms/payload","slug":"username-or-email-is-required","errorCode":null,"errorMessage":"Username or email is required","messagePattern":"Username or email is required","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"packages/payload/src/auth/ensureUsernameOrEmail.ts","lineNumber":57,"sourceCode":"    if (operation === 'create' && !data.email && !data.username) {\n      missingFields = true\n    } else if (operation === 'update') {\n      // prevent clearing both email and username\n      if ('email' in data && !data.email && 'username' in data && !data.username) {\n        missingFields = true\n      }\n      // prevent clearing email if no username\n      if ('email' in data && !data.email && !originalDoc.username && !data?.username) {\n        missingFields = true\n      }\n      // prevent clearing username if no email\n      if ('username' in data && !data.username && !originalDoc.email && !data?.email) {\n        missingFields = true\n      }\n    }\n\n    if (missingFields) {\n      throw new ValidationError(\n        {\n          collection: collectionSlug,\n          errors: [\n            {\n              message: 'Username or email is required',\n              path: 'username',\n            },\n            {\n              message: 'Username or email is required',\n              path: 'email',\n            },\n          ],\n        },\n        req.t,\n      )\n    }\n  }\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/payload/src/auth/ensureUsernameOrEmail.ts#L39-L75","documentation":"A Payload `ValidationError` raised by `ensureUsernameOrEmail` during auth collection create/update. It fires when the operation would leave the document with neither a username nor an email — for example clearing `email` on a doc that has no username, or clearing `username` on a doc that has no email, or creating a doc with both absent. The error reports two field-level errors (username and email) so the UI can flag both.","triggerScenarios":"PATCH/PUT on a users collection setting `email: ''` (or null) when the document's `username` is also empty; creating a user with `{ username: '', email: '' }`; the admin UI clearing the email field on a username-less account. Triggered regardless of which field is being mutated, as long as the end state has no identifier.","commonSituations":"A collection configured with `auth.loginWithUsername: { allowEmailLogin: false }` where the UI still lets users blank both; bulk imports that omit both fields; a custom update flow that nulls email for GDPR/privacy without first ensuring a username exists.","solutions":["Ensure at least one of `username` or `email` is non-empty after the operation: before clearing email, set a username (and vice versa).","If you legitimately want accounts with no contact identifier, disable this guard via a custom `ensureUsernameOrEmail` override only if the schema permits it.","In admin forms, make at least one of the two fields required at the form level so the request never reaches this guard."],"exampleFix":"// before — clearing email on an account with no username\nawait payload.update({ collection: 'users', id, data: { email: '' } })\n\n// after — set a username first, then clear email\nawait payload.update({ collection: 'users', id, data: { username: 'u' + id, email: '' } })","handlingStrategy":"validation","validationCode":"function hasIdentifier(data, original) {\n  const willHaveUsername = data.username ?? original?.username\n  const willHaveEmail = data.email ?? original?.email\n  return Boolean(willHaveUsername || willHaveEmail)\n}","typeGuard":null,"tryCatchPattern":"try {\n  await payload.update({ collection: 'users', id, data })\n} catch (e) {\n  if (e instanceof ValidationError && e.data?.errors?.some(er => er.message === 'Username or email is required')) {\n    // ensure username or email stays non-empty, then retry\n  }\n  throw e\n}","preventionTips":["Before clearing email, set a username (and vice versa).","Make at least one identifier required at the form layer.","In import scripts, populate one identifier for every row."],"tags":["payload","auth","validation","username","email","crud"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}