hcengineering/platform · error

'from' is missing

Error message

'from' is missing

What it means

The pod-mail service rejects a send-mail request with HTTP 400 because the 'from' address is absent. When the handler destructures the request body, fromAddress is undefined, so the service refuses to build a nodemailer SendMailOptions object. It logs a warning ('From address is missing in email request') and returns a structured error body instead of attempting delivery.

Source

Thrown at services/mail/pod-mail/src/main.ts:112

  const fromAddress = from ?? config.source
  if (text === undefined && html === undefined) {
    ctx.warn('Text and html are missing in email request', { from, to })
    res.status(400).send({ err: "'text' and 'html' are missing" })
    return
  }
  if (subject === undefined) {
    ctx.warn('Subject is missing in email request', { from, to })
    res.status(400).send({ err: "'subject' is missing" })
    return
  }
  if (to === undefined) {
    ctx.warn('To address is missing in email request', { from })
    res.status(400).send({ err: "'to' is missing" })
    return
  }
  if (fromAddress === undefined) {
    ctx.warn('From address is missing in email request', { to })
    res.status(400).send({ err: "'from' is missing" })
    return
  }
  const message: SendMailOptions = {
    from: fromAddress,
    to,
    subject,
    text
  }
  // When sending system message, ensure we enable replying to a different domain as needed
  if (config.replyTo !== undefined && fromAddress === config.source) {
    message.replyTo = config.replyTo
  }
  if (html !== undefined) {
    message.html = html
  }
  if (headers !== undefined) {
    message.headers = headers
  }

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Add a non-empty 'from' field to the JSON request body, e.g. {"from":"sender@example.com","to":"rcpt@example.com","subject":"hi"}.
  2. Verify the request Content-Type is application/json and the body actually parses (empty body means every field, including 'from', is undefined).
  3. Set a default sender in the calling code so every mail request includes it (e.g. from: config.defaultSender) instead of relying on per-call input.
  4. Check for typo'd field names like 'sender', 'fromAddress', or 'From' — the service looks for exactly 'from'.

Example fix

// before
await fetch(mailUrl, { method: 'POST', body: JSON.stringify({ to, subject }) })
// after
await fetch(mailUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ from: 'noreply@example.com', to, subject }) })
Defensive patterns

Strategy: validation

Validate before calling

function canSendMail(body: unknown): body is { from: string; to: string; subject: string } {
  const b = body as any
  return typeof b?.from === 'string' && b.from.includes('@') && typeof b?.to === 'string' && typeof b?.subject === 'string'
}
if (!canSendMail(payload)) throw new Error('mail request must include non-empty from/to/subject')

Type guard

const isFromAddress = (v: unknown): v is string => typeof v === 'string' && v.includes('@')

Try / catch

const res = await fetch(mailUrl, opts)
if (res.status === 400) {
  const { err } = await res.json()
  throw new Error(`Mail request rejected: ${err}`)
}

Prevention

When it happens

Trigger: POST to the mail endpoint with a body containing 'to' and 'subject' but no 'from' field, or a 'from' field explicitly set to null/undefined; also a request whose JSON body fails to parse so all fields default to undefined.

Common situations: Migrating from an older API version where the from address was configured server-side; forgetting that pod-mail requires a per-request sender rather than a default sender in config; template or mail-merge code that only fills recipient fields; sending with Content-Type not set to application/json so express body-parser leaves body empty.

Related errors


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