hcengineering/platform · error · Error
Failed to load server config
Error message
Failed to load server config
What it means
The mail service HTTP endpoint in services/mail/pod-mail/src/main.ts rejects a POST to the send-mail route with HTTP 400 when the request body has no 'subject' field. handleSendMail validates required fields (text/html, subject, to, from) sequentially and returns the first missing one as { err: "'subject' is missing" }. This is a deliberate input validation guard, not an internal failure.
Source
Thrown at desktop/src/ui/preload.ts:42
const newPath = path.slice(1)
return `${host}${newPath}`
} else {
return `${host}${path}`
}
}
async function loadServerConfig (url: string): Promise<any> {
let retries = 1
let res: Response | undefined
while (true) {
try {
res = await fetch(url, {
keepalive: true
})
if (res === undefined) {
// In theory should never get here
throw new Error('Failed to load server config')
}
break
} catch (e) {
retries++
await new Promise((resolve) => setTimeout(resolve, 1000 * Math.min(5, retries)))
}
}
return await res.json()
}
const openArg = (process.argv.find((it) => it.startsWith('--open=')) ?? '').split('--open=')[1]
console.log('Open passed', openArg)
let configPromise: Promise<Config> | undefined
const expose: IPCMainExposed = {
setBadge: (badge: number) => {
ipcRenderer.send(IpcMessage.SetBadge, badge)View on GitHub (pinned to 63e28dc964)
Solutions
- Add a non-empty 'subject' string to the request body before sending.
- If subject is optional by design, pass an empty string or a placeholder like '(no subject)'.
- Check the caller code that constructs the payload for undefined subject values being dropped by JSON.stringify.
- Return the error to the user or log it client-side instead of retrying the same payload.
Example fix
// before
await fetch(mailUrl, { method: 'POST', body: JSON.stringify({ from, to, text }) })
// after
await fetch(mailUrl, { method: 'POST', body: JSON.stringify({ from, to, text, subject: subject ?? '(no subject)' }) }) Defensive patterns
Strategy: validation
Validate before calling
if (typeof subject !== 'string' || subject.length === 0) {
throw new Error('subject is required before calling the mail endpoint')
} Type guard
function hasSubject(body: unknown): body is { subject: string; [k: string]: unknown } {
return typeof body === 'object' && body !== null && typeof (body as any).subject === 'string' && (body as any).subject.length > 0
} Try / catch
const res = await fetch(mailUrl, { method: 'POST', body })
if (res.status === 400) {
const { err } = await res.json()
if (err === "'subject' is missing") {
// surface a field-level validation message to the user instead of retrying
}
} Prevention
- Validate all required mail fields (subject, to, from, text/html) at the call site before building the request.
- Avoid undefined fields in payloads — JSON.stringify silently drops them; use explicit defaults like '(no subject)'.
- Write a shared payload builder for mail requests so required fields are enforced in one place.
When it happens
Trigger: POSTing to the mail endpoint with a JSON body that includes text or html, to, and from, but omits the 'subject' property (or sends it as null/undefined after JSON serialization drops it).
Common situations: Callers building the request dynamically where subject comes from user input or an upstream record that lacks a title; automated notification senders that only set the body; JSON.stringify silently dropping undefined subject values.
Related errors
- getDisplayMedia not supported
- No screen access granted
- 'from' is missing
- 'data' is missing
- 'subscriptions' is missing
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/de6e83a7958deddb.
Report an issue: GitHub.