transloadit/uppy · error · Error

onBeforeSnapshot: ${message}

Error message

onBeforeSnapshot: ${message}

What it means

Webcam's takeSnapshot first runs the user-supplied onBeforeSnapshot hook; if that hook throws or rejects, the error message is prefixed and rethrown as `onBeforeSnapshot: <message>`. The original message is also shown to the user via uppy.info.

Source

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

          clearInterval(countDown)
          this.uppy.info(this.i18n('smile'), 'success', 1500)
          setTimeout(() => resolve(), 1500)
        }
      }, 1000)
    })
  }

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

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Debug your onBeforeSnapshot callback — the suffixed text is your own error's message
  2. Make the hook resolve instead of reject for recoverable conditions, and catch expected failures inside it
  3. If using a countdown, resolve it (e.g. Promise.resolve) instead of rejecting on cancel

Example fix

// before
onBeforeSnapshot: () => Promise.reject(new Error('camera not ready'))

// after
onBeforeSnapshot: () => {
  if (!cameraReady) return Promise.resolve() // skip prep gracefully
  return prepareCamera()
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await webcam.takeSnapshot()
} catch (e) {
  if (e.message.startsWith('onBeforeSnapshot:')) {
    console.error('hook failed:', e.message.slice('onBeforeSnapshot:'.length))
  }
}

Prevention

When it happens

Trigger: Passing an onBeforeSnapshot option that throws or returns a rejected promise — e.g. a countdown routine that rejects, a permission check that fails, or a bug in the callback.

Common situations: Custom '3-2-1 countdown' or 'prepare camera' hooks; hooks doing await on user gesture/permission that can reject; throwing strings instead of Error objects in the callback (message becomes the string).

Related errors


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