hcengineering/platform · error
Content-Type header not found
Error message
Content-Type header not found
What it means
parseContent extracts the body and attachments from an incoming MTA email message. It first looks up the 'Content-Type' header via getHeader; RFC-822 messages should always carry one, so if it is absent the parser refuses to guess and throws 'Content-Type header not found'. Without the content type it cannot decide between text/plain handling, multipart parsing, etc.
Source
Thrown at services/mail/pod-mail-worker/src/utils.ts:33
import { randomUUID } from 'crypto'
import { readEml, ReadedEmlJson } from 'eml-parse-js'
import TurndownService from 'turndown'
import sanitizeHtml from 'sanitize-html'
import { MeasureContext } from '@hcengineering/core'
import { type Attachment } from '@hcengineering/mail-common'
import { MtaMessage } from './types'
import { getDecodedContent } from './decode'
export async function parseContent (
ctx: MeasureContext,
mta: MtaMessage
): Promise<{ content: string, attachments: Attachment[] }> {
// TODO: UBERF-11029 - remove this logging after testing
ctx.info('Parsing email content', { mta })
const contentType = getHeader(mta, 'Content-Type')
if (contentType === undefined) {
throw new Error('Content-Type header not found')
}
if (contentType.toLowerCase().startsWith('text/plain')) {
return { content: getDecodedContent(ctx, mta), attachments: [] }
}
const email = await getEmailContent(ctx, mta)
let content = email.text ?? ''
let isMarkdown = false
if (email.html !== undefined) {
try {
const html = sanitizeHtml(email.html)
const tds = new TurndownService()
content = tds.turndown(html)
isMarkdown = true
} catch (error) {View on GitHub (pinned to 63e28dc964)
Solutions
- Ensure the MTA/relay forwards the full header set, especially Content-Type
- Fix the message producer/test fixture to include a Content-Type header (e.g. 'text/plain; charset=utf-8')
- Wrap parseContent and fall back to treating the body as plain text when the header is missing
Example fix
// before
const contentType = getHeader(mta, 'Content-Type')
if (contentType === undefined) {
throw new Error('Content-Type header not found')
}
// after (caller-side fallback)
const result = await parseContent(ctx, mta).catch(() => ({ content: getDecodedContent(ctx, mta), attachments: [] })) Defensive patterns
Strategy: type-guard
Validate before calling
function hasContentType(mta: MtaMessage): boolean {
return mta.message.headers.some(([name]) => name.trim().toLowerCase() === 'content-type')
}
if (!hasContentType(mta)) throw new Error('MTA message missing Content-Type header') Type guard
function hasHeader(mta: MtaMessage, name: string): boolean {
return getHeader(mta, name) !== undefined
} Try / catch
try {
const { content, attachments } = await parseContent(ctx, mta)
} catch (e) {
if (e.message === 'Content-Type header not found') {
// treat as plain text fallback
} else throw e
} Prevention
- Verify upstream MTA/relay forwards the full header set
- Include Content-Type in all test MtaMessage fixtures
- Reject malformed messages at ingestion before parsing
- Monitor parse failures per source to catch header-stripping gateways
When it happens
Trigger: An email arrives via the MTA whose headers array lacks a 'Content-Type' entry — e.g. a stripped-down raw message forwarded by a relay, a hand-crafted MtaMessage in tests, or a mail pipeline that drops non-standard headers before calling parseContent.
Common situations: Upstream MTA or sanitizer rewriting/removing headers; test fixtures building MtaMessage objects with only a few headers; exotic gateways (SMS-to-email, fax-to-email) that emit minimal headers; TODO UBERF-11029 logging shows the mta object missing contentType in its headers array.
Related errors
- Invalid email address
- Unable to determine the required version of Rush from ${RUSH
- Invalid package specifier: ${rawPackageSpecifier}
- Failed to parse response for part ${partNumber}
- Invalid endpoint reference
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/06f55722ee824444.
Report an issue: GitHub.