garrytan/gstack · error · Error

Cannot use --viewport with --clip — choose one

Error message

Cannot use --viewport with --clip — choose one

What it means

Thrown when both `--viewport` and `--clip` are passed to `screenshot`. `--viewport` means 'capture only the visible viewport' (Playwright `fullPage:false`) while `--clip` supplies an explicit rectangle; supplying both is contradictory, so the guard at lines 495-496 rejects it before calling Playwright.

Source

Thrown at browse/src/meta-commands.ts:496

          outputPath = arg;
        }
      }

      // --selector flag takes precedence; conflict with positional selector.
      if (flagSelector !== undefined) {
        if (targetSelector !== undefined) {
          throw new Error('--selector conflicts with positional selector — choose one');
        }
        targetSelector = flagSelector;
      }

      validateOutputPath(outputPath);

      if (clipRect && targetSelector) {
        throw new Error('Cannot use --clip with a selector/ref — choose one');
      }
      if (viewportOnly && clipRect) {
        throw new Error('Cannot use --viewport with --clip — choose one');
      }

      // --base64 mode: capture to buffer instead of disk
      if (base64Mode) {
        let buffer: Buffer;
        if (targetSelector) {
          const resolved = await bm.resolveRef(targetSelector);
          const locator = 'locator' in resolved ? resolved.locator : page.locator(resolved.selector);
          buffer = await locator.screenshot({ timeout: 5000 });
        } else if (clipRect) {
          buffer = await page.screenshot({ clip: clipRect });
        } else {
          buffer = await page.screenshot({ fullPage: !viewportOnly });
          // Guard the most common API-bricking case (fullPage). Element /
          // clip captures usually stay within the cap; we still guard the
          // path-mode below for fullPage writes.
          ({ buffer } = await guardScreenshotBuffer(buffer));
        }

View on GitHub (pinned to 94993f7401)

Solutions

  1. Keep `--clip x,y,w,h` and remove `--viewport` to capture an explicit rectangle.
  2. Keep `--viewport` and remove `--clip` to capture only the visible viewport.
  3. For a full-page capture, remove both flags (full page is the default).

Example fix

// before
browse screenshot --viewport --clip 0,0,800,600 out.png
// after
browse screenshot --clip 0,0,800,600 out.png
Defensive patterns

Strategy: validation

Validate before calling

if (args.includes('--viewport') && args.includes('--clip')) {
  throw new Error('--viewport and --clip are mutually exclusive');
}

Try / catch

try { await browse.screenshot(args); }
catch (err) {
  if (/Cannot use --viewport with --clip/.test(err.message)) {
    args = args.filter(a => a !== '--viewport'); // pick one
  }
}

Prevention

When it happens

Trigger: `browse screenshot --viewport --clip 0,0,800,600 out.png` (lines 495-496).

Common situations: Confusing `--viewport` (visible-area capture) with `--clip` (arbitrary rectangle), or leaving a stale `--viewport` in a parameterized call.

Related errors


AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12). Data as JSON: /api/errors/6d6ba76954e9028e. Report an issue: GitHub.