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

  1. Pass only the local part (no '@') as name and a valid domain separately
  2. Check the composed name@domain with an email regex before calling
  3. 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

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


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/ad8bf0bf99eaefd6. Report an issue: GitHub.