hcengineering/platform · error
Failed to create PDF: ${err.message}
Error message
Failed to create PDF: ${err.message} What it means
docToPdf converts office documents to PDF using LibreOffice (soffice) with a temporary profile directory. After running the conversion it verifies the expected output file exists via fs access; if the PDF was not produced it throws this error with LibreOffice's stderr/err.message appended. It signals the office-to-PDF conversion pipeline failed.
Source
Thrown at pods/preview/src/utils/libreoffice.ts:92
reject(new Error(`LibreOffice exited with code ${code}`))
} else {
resolve()
}
})
proc.on('error', (err) => {
ctx.error('LibreOffice failed', { stdout, stderr, docFile, pdfFile })
reject(new Error(`Failed to start LibreOffice: ${err.message}`))
})
})
} finally {
await rm(profileDir, { recursive: true })
}
try {
await access(pdfFile)
} catch (err: any) {
throw new Error(`Failed to create PDF: ${err.message}`)
}
return pdfFile
}
View on GitHub (pinned to 63e28dc964)
Solutions
- Verify LibreOffice (soffice) is installed and executable on the host and works headless (soffice --headless --convert-to pdf test.docx).
- Check the wrapped err.message/LibreOffice stderr for the specific conversion failure (corrupt file, unsupported format, permissions).
- Test the specific document manually with the same soffice command; re-export/re-upload the file if it is corrupt.
- Check permissions on the temp/profile directories and available disk space and memory.
Example fix
// before
const pdfFile = await docToPdf(ctx, inputDocPath)
// after
if (!existsSync(inputDocPath) || statSync(inputDocPath).size === 0) {
throw new Error('source document missing or empty')
}
const pdfFile = await docToPdf(ctx, inputDocPath) Defensive patterns
Strategy: validation
Validate before calling
import { access, constants } from 'fs/promises'
await access(inputDocPath, constants.R_OK) // source must exist and be readable
if (statSync(inputDocPath).size === 0) throw new Error('empty document') Type guard
function isConvertibleDoc(contentType: string): boolean {
return /msword|openxmlformats|opendocument/.test(contentType)
} Try / catch
try {
const pdf = await docToPdf(ctx, docPath)
} catch (err) {
if (/Failed to create PDF/.test(err.message)) {
ctx.error('libreoffice conversion failed', { cause: err.message, docPath })
throw new Error('document conversion unavailable')
}
throw err
} Prevention
- Install and smoke-test LibreOffice headless in the deployment image.
- Check soffice profile dir permissions and HOME for the service user.
- Validate uploaded documents before conversion.
- Ensure enough memory/disk for soffice child processes.
When it happens
Trigger: Converting a doc/docx/odt (or similar) blob to PDF when soffice is missing, crashes, times out, or rejects the input file — so the output .pdf never appears on disk.
Common situations: Host without LibreOffice installed, HOME/profile-dir permission problems for the soffice process, password-protected or corrupt documents, resource exhaustion (memory/CPU) killing soffice, unsupported legacy formats.
Related errors
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/1a6085ad289fa4bf.
Report an issue: GitHub.