cefsharp/CefSharp · error · ArgumentException

{nameof(viewport)}.{nameof(viewport.Scale)} must be greater

Error message

{nameof(viewport)}.{nameof(viewport.Scale)} must be greater than 0.

What it means

Thrown by CaptureScreenshotAsync when a non-null viewport is supplied whose Scale property is <= 0. The scale is passed to CEF/DevTools which requires a positive device-scale factor; zero or negative would produce a degenerate image. The guard rejects invalid scale before resizing the view.

Source

Thrown at CefSharp.OffScreen/ChromiumWebBrowser.cs:597

        /// are larger than the current browser <see cref="Size"/>.</param>
        /// <returns>A task that can be awaited to obtain the screenshot as a byte[].</returns>
        public async Task<byte[]> CaptureScreenshotAsync(CaptureScreenshotFormat? format = null, int? quality = null, Viewport viewport = null)
        {
            ThrowExceptionIfDisposed();
            ThrowExceptionIfBrowserNotInitialized();

            using (var devToolsClient = browser.GetDevToolsClient())
            {
                if (viewport == null)
                {
                    var screenShot = await devToolsClient.Page.CaptureScreenshotAsync(format, quality, fromSurface: true).ConfigureAwait(continueOnCapturedContext: false);

                    return screenShot.Data;
                }

                if (viewport.Scale <= 0)
                {
                    throw new ArgumentException($"{nameof(viewport)}.{nameof(viewport.Scale)} must be greater than 0.");
                }

                //https://github.com/chromiumembedded/cef/issues/3103
                //CEF OSR mode doesn't set the size internally when CaptureScreenShot is called with a clip param specified, so
                //we must manually resize our view if size is greater
                var newWidth = viewport.Width + viewport.X;
                if (newWidth < size.Width)
                {
                    newWidth = size.Width;
                }
                var newHeight = viewport.Height + viewport.Y;
                if (newHeight < size.Height)
                {
                    newHeight = size.Height;
                }

                if ((int)newWidth > size.Width || (int)newHeight > size.Height || viewport.Scale != deviceScaleFactor)
                {

View on GitHub (pinned to 16bc6e0711)

Solutions

  1. Set viewport.Scale to a positive value (typically 1.0 for normal DPI, or your deviceScaleFactor).
  2. Pass viewport: null if you don't need a custom clip region.
  3. Guard scale > 0 before calling.

Example fix

// before
var vp = new Viewport { Width = 800, Height = 600, Scale = 0 };
await browser.CaptureScreenshotAsync(viewport: vp);

// after
var vp = new Viewport { Width = 800, Height = 600, Scale = 1.0f };
await browser.CaptureScreenshotAsync(viewport: vp);
Defensive patterns

Strategy: validation

Validate before calling

if (viewport != null && viewport.Scale <= 0) viewport.Scale = 1.0f;
await browser.CaptureScreenshotAsync(viewport: viewport);

Type guard

public static bool IsValidViewport(Viewport v) => v == null || v.Scale > 0;

Try / catch

try { return await browser.CaptureScreenshotAsync(viewport: vp); }
catch (ArgumentException ex) when (ex.Message.Contains("Scale")) { vp.Scale = 1.0f; /* retry */ }

Prevention

When it happens

Trigger: Constructing a Viewport with Scale = 0 (e.g. default struct value if not explicitly set) or a negative value and passing it to CaptureScreenshotAsync.

Common situations: Using `new Viewport { Width = 800, Height = 600 }` and forgetting Scale (defaults to 0). Computing scale dynamically and a division produced 0.

Related errors


AI-assisted analysis of cefsharp/CefSharp@16bc6e0711 (2026-08-13). Data as JSON: /api/errors/f4f75a779300cad0. Report an issue: GitHub.