Budibase/budibase · error · BadRequestError

Attempted to upload a file without a path

Error message

Attempted to upload a file without a path

What it means

Thrown by uploadFile when getUploadPath returns falsy for the uploaded part, i.e. the upload middleware produced no temporary file path to read the content from. The server cannot store a file it cannot locate on disk.

Source

Thrown at packages/server/src/api/controllers/static/index.ts:269

  const file = ctx.request?.files?.file
  if (!file) {
    throw new BadRequestError("No file provided")
  }

  let files = file && Array.isArray(file) ? Array.from(file) : [file]

  ctx.body = await Promise.all(
    files.map(async file => {
      const fileName = getUploadFilename(file)
      const filePath = getUploadPath(file)
      const rawMimeType = getUploadMimeType(file)
      if (!fileName) {
        throw new BadRequestError(
          "Attempted to upload a file without a filename"
        )
      }
      if (!filePath) {
        throw new BadRequestError("Attempted to upload a file without a path")
      }

      const extension = [...fileName.split(".")].pop()
      if (!extension) {
        throw new BadRequestError(
          `File "${fileName}" has no extension, an extension is required to upload a file`
        )
      }

      const extensionLower = extension.toLowerCase()
      const isPublicUser =
        ctx.roleId === roles.BUILTIN_ROLE_IDS.PUBLIC ||
        ctx.user?.roleId === roles.BUILTIN_ROLE_IDS.PUBLIC
      const enforceInvalidExtension = isPublicUser || !env.SELF_HOSTED
      if (
        enforceInvalidExtension &&
        InvalidFileExtensions.includes(extensionLower)
      ) {

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Resend the upload ensuring the file part includes actual content
  2. Raise the server/proxy body size limits if large files are being dropped
  3. Verify the multipart boundary and part structure from the client

Example fix

// before
fd.append('file', emptyBlob, 'x.png')  // 0 bytes
// after
fd.append('file', fileFromDisk, 'x.png')
Defensive patterns

Strategy: validation

Validate before calling

function uploadHasContent(file) {
  return Boolean(file && file.size > 0 && file.path !== undefined)
}

Type guard

const hasUploadPath = (f: unknown): f is { path: string } =>
  typeof f === 'object' && f !== null && typeof (f as any).path === 'string' && (f as any).path.length > 0

Try / catch

try {
  await api.uploadFile(fd)
} catch (err) {
  if (err instanceof BadRequestError && err.message.includes('without a path')) {
    // resend with a complete, non-empty file part
  } else throw err
}

Prevention

When it happens

Trigger: Multipart part arrived without file content (empty part), or the upload middleware (e.g. koa-body/busboy) did not write a temp file because the part was malformed or truncated.

Common situations: Interrupted/aborted uploads, oversized bodies rejected before write, misconfigured body parser limits, or sending a part with metadata but zero bytes.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/2a7f0a7bb8698746. Report an issue: GitHub.