{"record":{"id":"d0cf5e13da454b2a","repo":"transloadit/uppy","slug":"failed-to-get-screen-capture-stream","errorCode":null,"errorMessage":"Failed to get screen capture stream","messagePattern":"Failed to get screen capture stream","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@uppy/screen-capture/src/ScreenCapture.tsx","lineNumber":545,"sourceCode":"      type: mimeType,\n    }\n\n    return Promise.resolve(file)\n  }\n\n  async captureScreenshot(): Promise<void> {\n    if (!this.mediaDevices?.getDisplayMedia) {\n      throw new Error('Screen capture is not supported')\n    }\n\n    try {\n      let stream = this.videoStream\n\n      // Only request new stream if we don't have one\n      if (!stream) {\n        const newStream = await this.selectVideoStreamSource()\n        if (!newStream) {\n          throw new Error('Failed to get screen capture stream')\n        }\n        stream = newStream\n      }\n\n      const video = document.createElement('video')\n      video.srcObject = stream\n\n      await new Promise((resolve) => {\n        video.onloadedmetadata = () => {\n          video.play()\n          resolve(null)\n        }\n      })\n\n      const canvas = document.createElement('canvas')\n      canvas.width = video.videoWidth\n      canvas.height = video.videoHeight\n","sourceCodeStart":527,"sourceCodeEnd":563,"githubUrl":"https://github.com/transloadit/uppy/blob/5d4dedd02a1ac0ae022c75c54aca76558f88e256/packages/@uppy/screen-capture/src/ScreenCapture.tsx#L527-L563","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure a sharing session is active before enabling the screenshot button, or let the plugin request the stream via its own UI flow","Check iframe permissions and OS screen-recording permissions","Catch this error and show an informational message prompting the user to re-select a source"],"exampleFix":"// before\ntry { await plugin.captureScreenshot() } catch (e) { /* ? */ }\n\n// after\ntry {\n  await plugin.captureScreenshot()\n} catch (e) {\n  if (e.message === 'Failed to get screen capture stream') {\n    uppy.info('Please allow screen sharing and try again', 'error', 5000)\n  }\n}","handlingStrategy":"try-catch","validationCode":"const state = plugin.getPluginState()\nif (!state.videoStream && !navigator.mediaDevices?.getDisplayMedia) return // skip","typeGuard":null,"tryCatchPattern":"try {\n  await plugin.captureScreenshot()\n} catch (e) {\n  if (e.message === 'Failed to get screen capture stream') {\n    uppy.info('Screen sharing was cancelled or blocked — try again', 'error', 5000)\n  }\n}","preventionTips":["Confirm the screen-share session is active before exposing the screenshot action","Check iframe PermissionPolicy and OS screen-recording permissions upfront","Handle picker dismissal gracefully in UX"],"tags":["screen-capture","permission-denied","stream","getdisplaymedia"],"backgroundTag":"screen-share-permission-denied","analyzedSha":"5d4dedd02a1ac0ae022c75c54aca76558f88e256","analyzedAt":"2026-08-28T12:18:41.267Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}