hcengineering/platform · error · ApiError

File of this type (${stat.contentType}) cannot be converted

Error message

File of this type (${stat.contentType}) cannot be converted

What it means

Only DOCX files (content type application/vnd.openxmlformats-officedocument.wordprocessingml.document) are supported for HTML conversion. If the stored object's content type is anything else — PDF, image, legacy .doc, plain text — the endpoint rejects it with this 400 ApiError.

Source

Thrown at services/print/pod-print/src/server.ts:255

      res.contentType('application/json')
      res.send({ id: printId })
    })
  )

  app.get(
    '/convert/:file',
    wrapRequest(async (req, res, wsUuid) => {
      const convertableFormats = ['application/vnd.openxmlformats-officedocument.wordprocessingml.document']
      const ctx = req.ctx
      const file = req.params.file
      const stat = await storageAdapter.stat(ctx, wsUuid, file)

      if (stat === undefined) {
        throw new ApiError(404, `File ${file} not found`)
      }

      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')
        }

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Upload the file as genuine .docx and ensure the upload sets the correct DOCX MIME type.
  2. Convert legacy .doc/.odt files to .docx before uploading.
  3. If the file IS docx but stored with the wrong contentType, re-upload it with the correct MIME type (stored contentType is authoritative, not the filename).

Example fix

// before
form.append('file', docxFile, { type: 'application/octet-stream' })
// after
form.append('file', docxFile, { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' })
Defensive patterns

Strategy: validation

Validate before calling

const DOCX_MIME = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
function assertConvertibleFile (file: { contentType: string, name: string }): void {
  if (!file.name.toLowerCase().endsWith('.docx')) throw new Error('only .docx files can be converted')
  if (file.contentType !== DOCX_MIME) throw new Error(`stored contentType ${file.contentType} is not DOCX`)
}

Type guard

function isDocxFile (f: { contentType: string }): boolean {
  return f.contentType === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
}

Try / catch

try {
  const res = await fetch(`/convert/${encodeURIComponent(fileKey)}`, { headers })
  if (!res.ok) {
    const body = await res.json()
    if (body.code === 400 && /cannot be converted/.test(body.message)) {
      throw new Error(`Unsupported format: ${body.message} — convert to .docx first`)
    }
    throw new Error(body.message)
  }
  return await res.json()
} catch (err) { /* handle */ }

Prevention

When it happens

Trigger: GET /convert/:file on a file whose stored contentType is not the DOCX MIME type — e.g. uploading a .doc, .odt, .pdf, or a .docx that was uploaded with a wrong/generic content type like application/octet-stream.

Common situations: Upload pipeline stores files with application/octet-stream because the client didn't set MIME type; older files stored before content-type tracking; users renaming .doc to .docx; legacy Word formats.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/a801a8db1ad099bb. Report an issue: GitHub.