{"record":{"id":"46f95a2c651237b2","repo":"garrytan/gstack","slug":"screenshot-too-large-for-base64-10mb-use-dis","errorCode":null,"errorMessage":"Screenshot too large for --base64 (>10MB). Use disk path instead.","messagePattern":"Screenshot too large for --base64 \\(>10MB\\)\\. Use disk path instead\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"browse/src/meta-commands.ts","lineNumber":516,"sourceCode":"\n      // --base64 mode: capture to buffer instead of disk\n      if (base64Mode) {\n        let buffer: Buffer;\n        if (targetSelector) {\n          const resolved = await bm.resolveRef(targetSelector);\n          const locator = 'locator' in resolved ? resolved.locator : page.locator(resolved.selector);\n          buffer = await locator.screenshot({ timeout: 5000 });\n        } else if (clipRect) {\n          buffer = await page.screenshot({ clip: clipRect });\n        } else {\n          buffer = await page.screenshot({ fullPage: !viewportOnly });\n          // Guard the most common API-bricking case (fullPage). Element /\n          // clip captures usually stay within the cap; we still guard the\n          // path-mode below for fullPage writes.\n          ({ buffer } = await guardScreenshotBuffer(buffer));\n        }\n        if (buffer.length > 10 * 1024 * 1024) {\n          throw new Error('Screenshot too large for --base64 (>10MB). Use disk path instead.');\n        }\n        return `data:image/png;base64,${buffer.toString('base64')}`;\n      }\n\n      if (targetSelector) {\n        const resolved = await bm.resolveRef(targetSelector);\n        const locator = 'locator' in resolved ? resolved.locator : page.locator(resolved.selector);\n        await locator.screenshot({ path: outputPath, timeout: 5000 });\n        return `Screenshot saved (element): ${outputPath}`;\n      }\n\n      if (clipRect) {\n        await page.screenshot({ path: outputPath, clip: clipRect });\n        return `Screenshot saved (clip ${clipRect.x},${clipRect.y},${clipRect.width},${clipRect.height}): ${outputPath}`;\n      }\n\n      await page.screenshot({ path: outputPath, fullPage: !viewportOnly });\n      if (!viewportOnly) await guardScreenshotPath(outputPath);","sourceCodeStart":498,"sourceCodeEnd":534,"githubUrl":"https://github.com/garrytan/gstack/blob/94993f74012782fd94416dd44b8314f6363a13a4/browse/src/meta-commands.ts#L498-L534","documentation":"In `--base64` mode the screenshot is captured to an in-memory buffer and returned inline as a `data:image/png;base64,...` URI. A hard 10 MiB cap (lines 515-516) prevents the response from bricking JSON parsers, IPC channels, or LLM context windows. Only the base64 path enforces this; disk writes go through a separate path-size guard.","triggerScenarios":"`browse screenshot --base64` against a very tall page (fullPage default) whose PNG buffer exceeds 10*1024*1024 bytes (line 515). Most commonly a long scrollable page captured without `--viewport`.","commonSituations":"Agents piping screenshots into a chat/LLM context; CI capturing full-page regression shots of infinite-scroll or very long article pages.","solutions":["Drop `--base64` and pass a disk path so the PNG is written and only the path is returned: `browse screenshot out.png`.","Scope the capture with `--viewport` to limit it to the visible area.","Scope the capture with a selector (`--selector <css>` or `@ref`) or `--clip x,y,w,h` to shrink the buffer."],"exampleFix":"// before\nbrowse screenshot --base64\n// after\nbrowse screenshot --viewport out.png","handlingStrategy":"fallback","validationCode":"// Before --base64, estimate the page height; if very tall, prefer a path.\nconst viewport = await bm.getPage().viewportSize();\nconst estimatedBytes = (viewport?.width ?? 1280) * (await bm.getPage().evaluate(() => document.documentElement.scrollHeight)) * 3;\nif (estimatedBytes > 8 * 1024 * 1024) useDiskPath = true;","typeGuard":null,"tryCatchPattern":"try {\n  return await browse.screenshot(['--base64']);\n} catch (err) {\n  if (/too large for --base64/.test(err.message)) {\n    // fall back to disk capture and return the path\n    return await browse.screenshot(['out.png']);\n  }\n  throw err;\n}","preventionTips":["Default to disk paths for unknown page sizes; reserve --base64 for small element/clip captures.","Use --viewport or a selector to bound the capture region.","Track the 10 MiB cap as a named constant in your wrapper."],"tags":["screenshot","base64","memory","size-limit"],"backgroundTag":null,"analyzedSha":"94993f74012782fd94416dd44b8314f6363a13a4","analyzedAt":"2026-08-12T04:06:23.140Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}