transloadit/uppy · error · Error

File data is empty

Error message

File data is empty

What it means

#uploadLocalFile throws when constructing a tus.Upload because file.data is null/undefined. The Tus uploader needs the raw Blob/File bytes to upload, so an empty or missing data field cannot proceed.

Source

Thrown at packages/@uppy/tus/src/index.ts:487

      const allowedMetaFields = getAllowedMetaFields(
        opts.allowedMetaFields,
        file.meta,
      )
      allowedMetaFields.forEach((item) => {
        // tus type definition for metadata only accepts `Record<string, string>`
        // but in reality (at runtime) it accepts `Record<string, unknown>`
        // tus internally converts everything into a string, but let's do it here instead to be explicit.
        // because Uppy can have anything inside meta values, (for example relativePath: null is often sent by uppy)
        meta[item] = String(file.meta[item])
      })

      // tusd uses metadata fields 'filetype' and 'filename'
      copyProp(meta, 'type', 'filetype')
      copyProp(meta, 'name', 'filename')

      uploadOptions.metadata = meta

      if (file.data == null) throw new Error('File data is empty')
      upload = new tus.Upload(file.data, uploadOptions)
      this.uploaders[file.id] = upload
      const eventManager = new EventManager(this.uppy)
      this.uploaderEvents[file.id] = eventManager

      qRequest = () => {
        if (!file.isPaused) {
          upload.start()
        }
        // Don't do anything here, the caller will take care of cancelling the upload itself
        // using #resetUploaderReferences(). This is because #resetUploaderReferences() has to be
        // called when this request is still in the queue, and has not been started yet, too. At
        // that point this cancellation function is not going to be called.
        // Also, we need to remove the request from the queue _without_ destroying everything
        // related to this upload to handle pauses.
        return () => {}
      }

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Ensure uppy.addFile is always called with a real File/Blob in data
  2. If restoring files with Golden Retriever, re-attach data before upload or use @uppy/store-Cloudinary/restore mechanisms that preserve blobs
  3. For remote provider files, use Transloadit/Companion importFromUploadURLs or XHR upload with a Companion-proxied URL rather than Tus directly

Example fix

// before
uppy.addFile({ name: 'a.jpg', type: 'image/jpeg' }) // no data
// after
uppy.addFile({ name: file.name, type: file.type, data: file }) // real File
Defensive patterns

Strategy: type-guard

Validate before calling

for (const f of uppy.getFiles()) {
  if (f.data == null) uppy.removeFile(f.id)
}

Type guard

const hasData = (file: { data?: unknown }): boolean => file.data instanceof Blob || typeof ArrayBuffer.isView(file.data) === 'boolean' && ArrayBuffer.isView(file.data)

Prevention

When it happens

Trigger: Uploading a file whose uppy file object has data == null — e.g. files added with only metadata, restored files whose data was not reattached, or remote/provider files being fed to Tus without importFromUploadURLs.

Common situations: Using Golden Retriever restoration without restoring file blobs; adding files via uppy.addFile({ name, type }) with no data; sending provider files (Google Drive etc.) to Tus instead of Companion-based upload.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28). Data as JSON: /api/errors/853314c9d5564fb3. Report an issue: GitHub.