hcengineering/platform · error · ApiError
Failed to convert
Error message
Failed to convert
What it means
convertToHtml returned undefined, meaning the DOCX→HTML conversion library failed to produce output for the given buffer. The service raises this 400 ApiError rather than caching or returning an empty conversion. The specific parser failure is only visible in service logs.
Source
Thrown at services/print/pod-print/src/server.ts:271
if (!convertableFormats.includes(stat.contentType)) {
throw new ApiError(400, `File of this type (${stat.contentType}) cannot be converted`)
}
const convertId = getConvertId(file, stat.etag)
const convertStats = await storageAdapter.stat(ctx, wsUuid, convertId)
if (convertStats === undefined) {
const originalFile = await storageAdapter.read(ctx, wsUuid, file)
if (originalFile === undefined) {
throw new ApiError(404, `File ${file} not found`)
}
const htmlRes = await ctx.with('convertToHtml', {}, () => convertToHtml(Buffer.concat(originalFile as any)))
if (htmlRes === undefined) {
throw new ApiError(400, 'Failed to convert')
}
const htmlBuf = Buffer.from(htmlRes)
await storageAdapter.put(ctx, wsUuid, convertId, htmlBuf, 'text/html', htmlBuf.length)
}
res.contentType('application/json')
res.send({ id: convertId })
})
)
app.get(
'/print/:objectClass/:objectId',
wrapRequest(async (req, res, wsIds, wsLoginInfo) => {
const ctx = req.ctx
const objectId = req.params.objectId
const objectClass = req.params.objectClassView on GitHub (pinned to 63e28dc964)
Solutions
- Open the DOCX locally to verify it isn't corrupt or password-protected.
- Re-upload the file (re-upload fixes truncated uploads) and retry conversion.
- Re-save/export the document from Word/LibreOffice to normalize the OOXML, then re-upload.
- Check the print service logs for the converter's underlying exception to identify the unsupported feature.
Defensive patterns
Strategy: fallback
Validate before calling
// Sanity-check the DOCX before asking the service to convert
async function looksLikeDocx (file: File): Promise<boolean> {
const head = new Uint8Array(await file.slice(0, 2).arrayBuffer())
return head[0] === 0x50 && head[1] === 0x4b // ZIP magic 'PK' — DOCX is a zip container
} Try / catch
try {
const res = await fetch(`/convert/${encodeURIComponent(fileKey)}`, { headers })
if (!res.ok) {
const body = await res.json()
if (body.code === 400 && /Failed to convert/.test(body.message)) {
// surface a user-facing 'document could not be converted, try re-saving it' message
throw new ConvertError(body.message)
}
throw new Error(body.message)
}
return await res.json()
} catch (err) { /* handle: prompt user to re-export the DOCX */ } Prevention
- Validate uploads: check the ZIP magic bytes and that the docx opens in a parser before storing.
- Reject password-protected documents at upload time.
- Ask users to re-save/export from Word or LibreOffice if conversion fails.
- Check print-service converter logs for the exact parse failure to guide users.
When it happens
Trigger: GET /convert/:file where the stored DOCX is corrupt, truncated, password-protected, uses unsupported Word features, or the uploaded bytes are not actually DOCX despite the stored content type.
Common situations: Files corrupted by interrupted uploads; password-protected documents; files renamed to .docx but really another format; mammoth-style converters choking on exotic OOXML features.
Related errors
- File of this type (${stat.contentType}) cannot be converted
- Failed to load server config
- getDisplayMedia not supported
- No screen access granted
- Unknown step: ${step.name}
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/4b99576e3e8716b8.
Report an issue: GitHub.