hcengineering/platform · warning
'to' is missing
Error message
'to' is missing
What it means
handleSendMail returns HTTP 400 { err: "'to' is missing" } when the to field is absent from the request body. The recipient is mandatory; unlike from (which can fall back to config.source), to has no default, so the request is rejected.
Source
Thrown at services/mail/pod-mail/src/main.ts:107
to
})
res.status(401).send({ err: 'Unauthorized' })
return
}
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) {View on GitHub (pinned to 63e28dc964)
Solutions
- Include the to field (recipient address or array) in the request body.
- Check for field-name mismatches (recipients/email) between client and pod-mail's expected to.
- Validate the payload has to before calling the endpoint (see validationCode in defense section).
Example fix
// before
const body = { from, subject, text } // 400: to missing
// after
const body = { from, to: 'user@example.com', subject, text } Defensive patterns
Strategy: validation
Validate before calling
function assertRecipient(m: { to?: string | string[] }): void {
const to = m.to
const ok = typeof to === 'string' ? to.length > 0 : Array.isArray(to) && to.length > 0
if (!ok) throw new Error("email requires a 'to' recipient")
} Type guard
function hasRecipient(m: { to?: unknown }): m is { to: string | string[] } {
return typeof m.to === 'string' || Array.isArray(m.to)
} Try / catch
assertRecipient(mail)
const res = await fetch(mailUrl, { method: 'POST', body: JSON.stringify(mail) })
if (res.status === 400) throw new Error(`mail rejected: ${(await res.json()).err}`) Prevention
- Unlike from, 'to' has no server-side default — always supply it.
- Check for field-name drift (recipients/email) in client wrappers.
- Validate recipients exist before calling bulk-mail routines.
- Add schema validation (e.g. zod) on outbound mail payloads.
When it happens
Trigger: POST to the send-mail endpoint with from/subject/body present but to undefined — e.g. missing recipients array in the payload, a client wrapper dropping the field, or sending recipients in a different field name like recipients or email.
Common situations: Bulk-mail code that forgot to populate the recipient list; renaming to -> recipients in a shared client; serialization stripping undefined fields; sending single-recipient mail with the address in the wrong property.
Related errors
- 'text' and 'html' are missing
- 'subject' is missing
- Failed to load server config
- getDisplayMedia not supported
- No screen access granted
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/d93ccb6489048bef.
Report an issue: GitHub.