transloadit/uppy · error · Error

File data is empty

Error message

File data is empty

What it means

After Webcam's getImage() produces a Blob, takeSnapshot verifies that file.data is non-null and throws 'File data is empty' if the captured blob is missing. This indicates the underlying canvas/blob capture produced nothing.

Source

Thrown at packages/@uppy/webcam/src/Webcam.tsx:595

  async takeSnapshot(): Promise<void> {
    if (this.captureInProgress) return

    this.captureInProgress = true

    try {
      await this.opts.onBeforeSnapshot()
    } catch (err) {
      const message = typeof err === 'object' ? err.message : err
      this.uppy.info(message, 'error', 5000)
      throw new Error(`onBeforeSnapshot: ${message}`)
    }

    try {
      const file = await this.getImage()
      this.capturedMediaFile = file

      if (file.data == null) throw new Error('File data is empty')
      // Create object URL for preview
      const capturedSnapshotUrl = URL.createObjectURL(file.data)
      this.setPluginState({ capturedSnapshot: capturedSnapshotUrl })
      this.captureInProgress = false
    } catch (error) {
      // Logging the error, except restrictions, which is handled in Core
      this.captureInProgress = false
      if (!error.isRestriction) {
        this.uppy.log(error)
      }
    }
  }

  async getImage(): Promise<
    Pick<LocalUppyFileNonGhost<M, B>, 'data' | 'name'>
  > {
    const video = this.getVideoElement()
    if (!video) {

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Ensure the webcam stream is live and the video has rendered frames before enabling the snapshot button
  2. Re-acquire the camera stream if the track ended, then retry the snapshot
  3. Await video.play()/loadedmetadata before capturing so videoWidth/videoHeight are non-zero

Example fix

// before
onClick={() => webcam.getSnapshotButtonProps().onClick()}

// after
const state = webcam.getPluginState()
if (state.cameraReady && !state.capturedMediaFile) {
  webcam.getSnapshotButtonProps().onClick()
}
Defensive patterns

Strategy: validation

Validate before calling

const track = stream.getVideoTracks()[0]
if (track?.readyState === 'live' && videoRef.videoWidth > 0) {
  webcam.getSnapshotButtonProps().onClick()
}

Type guard

const isLiveCamera = (s: MediaStream | null): boolean =>
  !!s && s.getVideoTracks().some((t) => t.readyState === 'live')

Try / catch

try { await webcam.takeSnapshot() } catch (e) { if (e.message === 'File data is empty') uppy.info('Camera not ready, try again', 'error', 3000) }

Prevention

When it happens

Trigger: getImage() resolving with a file whose data is null/undefined — e.g. canvas.toBlob callback never fired, video track stopped mid-capture, or zero-dimension canvas producing no blob.

Common situations: Camera track ended (user/OS revoked permission) right at snapshot time, snapshot taken before the video has frames, or browser quirks where toBlob yields null (e.g. tainted/zero-size canvas).

Related errors


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