transloadit/uppy · error · Error

Failed to get screen capture stream

Error message

Failed to get screen capture stream

What it means

Thrown by captureScreenshot when there is no existing videoStream and a fresh call to selectVideoStreamSource() returns a falsy value, so no screen stream could be obtained for the screenshot. It mirrors the recording-path error but for the single-frame screenshot flow.

Source

Thrown at packages/@uppy/screen-capture/src/ScreenCapture.tsx:545

      type: mimeType,
    }

    return Promise.resolve(file)
  }

  async captureScreenshot(): Promise<void> {
    if (!this.mediaDevices?.getDisplayMedia) {
      throw new Error('Screen capture is not supported')
    }

    try {
      let stream = this.videoStream

      // Only request new stream if we don't have one
      if (!stream) {
        const newStream = await this.selectVideoStreamSource()
        if (!newStream) {
          throw new Error('Failed to get screen capture stream')
        }
        stream = newStream
      }

      const video = document.createElement('video')
      video.srcObject = stream

      await new Promise((resolve) => {
        video.onloadedmetadata = () => {
          video.play()
          resolve(null)
        }
      })

      const canvas = document.createElement('canvas')
      canvas.width = video.videoWidth
      canvas.height = video.videoHeight

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Ensure a sharing session is active before enabling the screenshot button, or let the plugin request the stream via its own UI flow
  2. Check iframe permissions and OS screen-recording permissions
  3. Catch this error and show an informational message prompting the user to re-select a source

Example fix

// before
try { await plugin.captureScreenshot() } catch (e) { /* ? */ }

// after
try {
  await plugin.captureScreenshot()
} catch (e) {
  if (e.message === 'Failed to get screen capture stream') {
    uppy.info('Please allow screen sharing and try again', 'error', 5000)
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

const state = plugin.getPluginState()
if (!state.videoStream && !navigator.mediaDevices?.getDisplayMedia) return // skip

Try / catch

try {
  await plugin.captureScreenshot()
} catch (e) {
  if (e.message === 'Failed to get screen capture stream') {
    uppy.info('Screen sharing was cancelled or blocked — try again', 'error', 5000)
  }
}

Prevention

When it happens

Trigger: Calling captureScreenshot() when this.videoStream is null (no active sharing session) and the internal stream selection resolves false — e.g. getDisplayMedia rejected because the user dismissed the picker, or permission was denied.

Common situations: User cancels the browser's screen-share dialog, PermissionPolicy blocks capture in an iframe, or OS-level screen recording permission (macOS) was denied, then the screenshot button is clicked.

Related errors


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