{"record":{"id":"6020529daf2a6bcd","repo":"Hmbown/CodeWhale","slug":"screenshot-failed-r-stderr-r-stdout-trim-slice-0-300","errorCode":null,"errorMessage":"screenshot failed: ${(r.stderr || r.stdout).trim().slice(0, 300)}","messagePattern":"screenshot failed: (.+?)","errorType":"exception","errorClass":"ExecError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/backends/win32.mjs","lineNumber":348,"sourceCode":"    },\n    screenshot: async (args = {}) => {\n      if (Object.hasOwn(args, \"app_ref\") || Object.hasOwn(args, \"window_id\")) throw unsupportedSelector(\"Windows screenshot does not support app_ref or window_id; omit them for a desktop screenshot\");\n      const { display, region, path: outPath } = args;\n      const dir = recordingsDir();\n      fs.mkdirSync(dir, { recursive: true });\n      const file = outPath || path.join(dir, `shot-${new Date().toISOString().replace(/[:.]/g, \"-\")}-${crypto.randomBytes(3).toString(\"hex\")}.png`);\n      const winPath = file.replace(/\\\\/g, \"\\\\\\\\\");\n      const script = `Add-Type -AssemblyName System.Windows.Forms; Add-Type -AssemblyName System.Drawing;\n$bounds = [System.Windows.Forms.SystemInformation]::VirtualScreen;\n$bmp = New-Object System.Drawing.Bitmap($bounds.Width, $bounds.Height);\n$g = [System.Drawing.Graphics]::FromImage($bmp);\n$g.CopyFromScreen($bounds.X, $bounds.Y, 0, 0, $bounds.Size);\n$g.Dispose();\n$bmp.Save('${file.replace(/'/g, \"''\")}', [System.Drawing.Imaging.ImageFormat]::Png);\n$bmp.Dispose();\nWrite-Output '{\"ok\": true, \"w\": ' + $bounds.Width + ', \"h\": ' + $bounds.Height + '}';`;\n      const r = await ps(script, { timeoutMs: 30_000 });\n      if (r.code !== 0 || !fs.existsSync(file)) throw new ExecError(`screenshot failed: ${(r.stderr || r.stdout).trim().slice(0, 300)}`, r);\n      const meta = tryJson(r.stdout.trim().split(\"\\n\").pop(), {});\n      lastRaster = { file, bytes: fs.statSync(file).size, points: { x: 0, y: 0, w: meta.w, h: meta.h }, pixels: { w: meta.w, h: meta.h }, scale: 1, capturedAt: new Date().toISOString() };\n      return { ...lastRaster };\n    },\n    zoom: async ({ source, region, path: outPath }) => {\n      const src = source ?? lastRaster?.file;\n      if (!src) throw new ExecError(\"no screenshot taken yet on this computer — call screenshot first\");\n      const out = outPath || path.join(recordingsDir(), `zoom-${crypto.randomBytes(4).toString(\"hex\")}.png`);\n      const script = `Add-Type -AssemblyName System.Drawing;\n$img = [System.Drawing.Image]::FromFile('${src.replace(/'/g, \"''\")}');\n$rect = New-Object System.Drawing.Rectangle(${Math.round(region[0])}, ${Math.round(region[1])}, ${Math.round(region[2])}, ${Math.round(region[3])});\n$bmp = New-Object System.Drawing.Bitmap($rect.Width, $rect.Height);\n$g = [System.Drawing.Graphics]::FromImage($bmp);\n$g.DrawImage($img, (New-Object System.Drawing.Rectangle(0, 0, $rect.Width, $rect.Height)), $rect, [System.Drawing.GraphicsUnit]::Pixel);\n$g.Dispose();\n$bmp.Save('${out.replace(/'/g, \"''\")}', [System.Drawing.Imaging.ImageFormat]::Png);\n$bmp.Dispose(); $img.Dispose();\nWrite-Output '{\"ok\": true}';`;","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/plugins/computer-use/src/backends/win32.mjs#L330-L366","documentation":"The win32 screenshot action runs a System.Drawing CopyFromScreen script via ps() with a 30s timeout, then requires both a zero exit code and that the expected PNG file exists on disk. Either condition failing throws this ExecError with up to 300 chars of stderr/stdout explaining the capture failure.","triggerScenarios":"screenshot() where the PowerShell capture script exits nonzero (Add-Type/GDI failure, session without a desktop) or exits 0 but the output PNG file was never written to recordingsDir().","commonSituations":"Running in a session without an interactive desktop (Session 0 service, SSH without console); GDI+ / System.Drawing broken on the host; antivirus blocking the PNG write; disk full so bmp.Save fails; multi-monitor coordinate issues producing a zero-size capture.","solutions":["Read the stderr/stdout excerpt in the message for the actual capture error","Ensure the process runs in an interactive desktop session (not a service/SSH headless session)","Verify System.Drawing/GDI+ works on the host and recordingsDir() is writable with free disk space","Retry once — transient session/disconnect states (RDP detach) break CopyFromScreen"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const shot = await computer.screenshot();\n} catch (e) {\n  if (/screenshot failed/.test(e.message)) {\n    // check session has an interactive desktop; retry once after a short delay\n  }\n}","preventionTips":["Ensure the automation runs inside an interactive desktop session (no Session 0/SSH headless)","Verify recordingsDir() is writable and has free disk space","Confirm System.Drawing/GDI+ is functional on the host before batch runs"],"tags":["windows","screenshot","gdi","capture-failed"],"backgroundTag":"file-write-failed","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T21:17:16.096Z"}