payloadcms/payload · error · ValidationError
A user with the given email is already registered.
Error message
A user with the given email is already registered.
What it means
Same `registerLocalStrategy` check, but fires when `canLoginWithUsername` is false (standard email auth). Throws a `ValidationError` with the localized `userEmailAlreadyRegistered` message on the `email` path when an existing user matches the email.
Source
Thrown at packages/payload/src/auth/strategies/local/register.ts:68
whereConstraint.or?.push({
username: {
equals: doc.username,
},
})
}
}
const existingUser = await payload.find({
collection: collection.slug,
depth: 0,
limit: 1,
pagination: false,
req,
where: whereConstraint,
})
if (existingUser.docs.length > 0) {
throw new ValidationError({
collection: collection.slug,
errors: [
canLoginWithUsername
? {
message: req.t('error:usernameAlreadyRegistered'),
path: 'username',
}
: { message: req.t('error:userEmailAlreadyRegistered'), path: 'email' },
],
})
}
const { hash, salt } = await generatePasswordSaltHash({ collection, password, req })
const sanitizedDoc = { ...doc }
if (sanitizedDoc.password) {
delete sanitizedDoc.password
}View on GitHub (pinned to 00c58b35c0)
Solutions
- Use a unique email.
- Pre-check email existence with `payload.find`.
- Add a DB unique index on the email column.
Example fix
// before
await payload.create({ collection: 'users', data: { email: 'a@b.com', password, ... } })
// after
const exists = await payload.find({ collection: 'users', limit: 1, pagination: false, where: { email: { equals: 'a@b.com' } } })
if (exists.docs.length) throw new Error('email registered')
await payload.create({ collection: 'users', data: { email: 'a@b.com', password, ... } }) Defensive patterns
Strategy: try-catch
Validate before calling
async function isEmailAvailable(payload, slug, email) {
const res = await payload.find({ collection: slug, limit: 1, pagination: false, where: { email: { equals: email } } })
return res.docs.length === 0
} Type guard
function isValidationError(e): e is ValidationError {
return e?.name === 'ValidationError' && Array.isArray(e?.data?.errors)
} Try / catch
try {
await payload.create({ collection: 'users', data })
} catch (e) {
if (isValidationError(e) && e.data.errors.some(x => x.path === 'email')) {
setFieldError('email', 'already registered')
} else throw e
} Prevention
- Pre-check email and enforce DB uniqueness.
- Map the `ValidationError` to the email field on the form.
When it happens
Trigger: Registering with an email that already exists in an email-login auth collection.
Common situations: Duplicate signup with the same email; re-running seeders; email column lacking a DB-level unique constraint.
Related errors
- A user with the given username is already registered.
- Username or email is required
- Email is required.
- Attachment is missing filename
- Attachment is missing both content and path
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/33ca3032a3bb670d.
Report an issue: GitHub.