hcengineering/platform · warning

missing files

Error message

missing files

What it means

handleUploadFormData requires multipart file uploads to carry at least one file. req.files is produced by the file-upload middleware; if it is null/undefined the handler responds 400 'missing files'. It prevents empty uploads from creating phantom blob entries.

Source

Thrown at services/datalake/pod-datalake/src/handlers/blob.ts:250

    res.status(204).send()
  } catch (error: any) {
    Analytics.handleError(error)
    ctx.error('failed to delete blob', { workspace, name, error })
    res.status(500).send()
  }
}

export async function handleUploadFormData (
  ctx: MeasureContext,
  req: Request,
  res: Response,
  datalake: Datalake,
  tempDir: TemporaryDir
): Promise<void> {
  const workspace = req.params.workspace as WorkspaceUuid

  if (req.files == null) {
    res.status(400).send('missing files')
    return
  }

  const files: [UploadedFile, key: string][] = []
  Object.entries(req.files).forEach(([key, value]) => {
    files.push([value as UploadedFile, key])
  })

  const result = await Promise.all(
    files.map(async ([file, key]) => {
      try {
        const name = file.name
        const size = file.size
        const contentType = file.mimetype

        let sha256: string
        try {
          sha256 =

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Send the request as multipart/form-data with at least one file part (e.g. curl -F 'name=@file').
  2. Do not set Content-Type manually; let the HTTP client add the multipart boundary.
  3. Check that MaxFileSize limits in server config are not rejecting the file before req.files is populated.

Example fix

// before
curl -X POST $URL -H 'Content-Type: application/json' -d '{"name":"f"}'
// after
curl -X POST $URL -F 'name=@./file.bin'
Defensive patterns

Strategy: validation

Validate before calling

if (!files || files.length === 0) {
  throw new Error('at least one file must be selected for upload')
}

Type guard

function hasFiles(b: unknown): b is Record<string, File> {
  return !!b && typeof b === 'object' && Object.keys(b as object).length > 0
}

Try / catch

const res = await fetch(url, { method: 'POST', body: form })
if (res.status === 400 && (await res.text()).includes('missing files')) {
  throw new Error('no file parts were attached to the multipart request')
}

Prevention

When it happens

Trigger: POSTing multipart/form-data to the upload endpoint with no file parts, sending fields only, or using a Content-Type other than multipart/form-data so the middleware never populates req.files.

Common situations: curl uploads without -F (using -d instead); clients setting the wrong Content-Type manually; middleware file-size/field limits silently dropping the file parts.

Related errors


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