hcengineering/platform · error · PlatformError
platform.status.MailboxError
platform.status.MailboxError
Error message
throw new PlatformError(new Status(Severity.ERROR, platform.status.MailboxError, { reason: 'invalid-name' })) What it means
createMailbox throws MailboxError with reason 'invalid-name' when, after cleaning, the name or domain normalizes to an empty string or the composed mailbox fails the isEmail check. Unlike the earlier BadRequest, the raw inputs were present but did not form a valid email address.
Source
Thrown at server/account/src/operations.ts:2602
params: {
name: string
domain: string
}
): Promise<{ mailbox: string, socialId: PersonId }> {
const { name, domain } = params
if (name == null || name === '' || domain == null || domain === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account } = decodeTokenVerbose(ctx, token)
const normalizedName = cleanEmail(name)
const normalizedDomain = cleanEmail(domain)
const mailbox = normalizedName + '@' + normalizedDomain
const opts = await getMailboxOptions(ctx, db, branding, token)
if (normalizedName.length === 0 || normalizedDomain.length === 0 || !isEmail(mailbox)) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.MailboxError, { reason: 'invalid-name' }))
}
if (!opts.availableDomains.includes(normalizedDomain)) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.MailboxError, { reason: 'domain-not-found' }))
}
if (normalizedName.length < opts.minNameLength || normalizedName.length > opts.maxNameLength) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.MailboxError, { reason: 'name-rules-violated' }))
}
if ((await db.mailbox.findOne({ mailbox })) !== null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.MailboxError, { reason: 'mailbox-exists' }))
}
const mailboxes = await db.mailbox.find({ accountUuid: account })
if (mailboxes.length >= opts.maxMailboxCount) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.MailboxError, { reason: 'mailbox-count-limit' }))
}
await db.mailbox.insertOne({ accountUuid: account, mailbox })
await db.mailboxSecret.insertOne({ mailbox, secret: generatePassword() })View on GitHub (pinned to 63e28dc964)
Solutions
- Pass only the local part (no '@') as name and a valid domain separately
- Check the composed name@domain with an email regex before calling
- Strip/reject characters that cleanEmail will remove
Example fix
// before
await createMailbox(ctx, db, branding, token, { name: 'john doe@x.com', domain: 'example.com' })
// after
await createMailbox(ctx, db, branding, token, { name: 'john.doe', domain: 'example.com' }) Defensive patterns
Strategy: validation
Validate before calling
const emailRe = /^[^@\s]+@[^@\s]+\.[^@\s]+$/
function validMailboxShape(name, domain) {
const n = name.replace(/[^a-z0-9._-]/gi, '')
return n.length > 0 && domain.length > 0 && emailRe.test(`${n}@${domain}`) && !name.includes('@')
} Type guard
function isValidMailboxInput(p: { name: string, domain: string }): boolean {
return p.name.length > 0 && p.domain.length > 0 && /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(`${p.name}@${p.domain}`)
} Try / catch
try {
return await createMailbox(ctx, db, branding, token, params)
} catch (err) {
if (getErrorReason(err) === 'invalid-name') {
throw new InvalidMailboxName('name/domain must form a valid email after cleaning')
} throw err
} Prevention
- Never pass a full email address in the name field
- Pre-validate with the same email regex the server uses (isEmail)
- Reject names consisting only of characters cleanEmail strips
When it happens
Trigger: name contains only characters stripped by cleanEmail (e.g. '@', spaces), domain is malformed, or the combination 'name@domain' is not a syntactically valid email.
Common situations: User enters a full email ('user@x.com') in the name field, producing 'user@x.com@domain'; name made entirely of illegal characters; domain with typos like 'com' or 'domain .com'.
Related errors
- Failed to load server config
- getDisplayMedia not supported
- No screen access granted
- Message id is required
- Message id is required
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/ad8bf0bf99eaefd6.
Report an issue: GitHub.