tui-cs/Terminal.Gui · error · ArgumentOutOfRangeException
Zoom level must be a finite number.
Error message
Zoom level must be a finite number.
What it means
Thrown by ImageView.SetZoomLevel when the supplied zoomLevel is NaN or infinite. Zoom is a multiplier applied to source pixel dimensions and used in clamp/compare math, so a non-finite value would poison layout and rendering arithmetic. The value is clamped to [GetMinimumZoomLevel(), MAX_ZOOM_LEVEL] after the check, so only truly broken numbers (division-by-zero results, uninitialised doubles) reach the guard.
Source
Thrown at Terminal.Gui/Views/ImageView/ImageView.Input.cs:68
_centerX = centerX;
_centerY = centerY;
ClampCenter ();
if (Math.Abs (previousCenterX - _centerX) < double.Epsilon && Math.Abs (previousCenterY - _centerY) < double.Epsilon)
{
return false;
}
InvalidateScaledImage ();
return true;
}
private bool SetZoomLevel (double zoomLevel, Point? anchor)
{
if (double.IsNaN (zoomLevel) || double.IsInfinity (zoomLevel))
{
throw new ArgumentOutOfRangeException (nameof (zoomLevel), @"Zoom level must be a finite number.");
}
double previousZoomLevel = _zoomLevel;
double clampedZoomLevel = Math.Clamp (zoomLevel, GetMinimumZoomLevel (), MAX_ZOOM_LEVEL);
if (Math.Abs (previousZoomLevel - clampedZoomLevel) < double.Epsilon)
{
return false;
}
if (anchor is { } position && TryMapViewportPointToSourceCenter (position, out double sourceX, out double sourceY))
{
_zoomLevel = clampedZoomLevel;
SetCenterForAnchor (position, sourceX, sourceY);
}
else
{
_zoomLevel = clampedZoomLevel;View on GitHub (pinned to 2e47b11478)
Solutions
- Guard the divisor before computing zoom: if (image.Width == 0) return; double zoom = viewport / (double)image.Width;
- Sanitise external input with double.IsFinite(zoomLevel) before calling SetZoomLevel or setting ZoomLevel.
- Default uninitialized zoom fields to a finite sentinel (e.g. 1.0) rather than leaving them as NaN.
- Use the public clamped API (ZoomLevel property) which routes through the same guard, so fix the source of the bad value upstream.
Example fix
// before double zoom = viewportWidth / (double)image.Width; // NaN if Width==0 imageView.ZoomLevel = zoom; // after double zoom = image.Width > 0 ? viewportWidth / (double)image.Width : 1.0; imageView.ZoomLevel = zoom;
Defensive patterns
Strategy: validation
Validate before calling
double zoom = ComputeZoom();
if (!double.IsFinite(zoom))
{
zoom = 1.0; // safe default
}
imageView.ZoomLevel = zoom; Type guard
static bool IsValidZoom(double z) => double.IsFinite(z) && z > 0;
Prevention
- Check the divisor before dividing when computing zoom from dimensions.
- Sanitise deserialised/config zoom values with double.IsFinite before use.
- Default numeric fields to a finite sentinel, never NaN.
When it happens
Trigger: Computing zoomLevel from a ratio where the denominator is zero or infinity (e.g. image.Width == 0 -> width/0.0); reading zoom from parsed/config data that defaulted to NaN; chaining double transformations that accumulate NaN via 0*Inf.
Common situations: Auto-fit logic that divides by an image dimension before the image has loaded; JSON/deserialised config where the field was never set; math derived from an empty viewport size.
Related errors
- Maximum sixel palette colors must be greater than zero.
- The source stream must be seekable (CanSeek property)
- No raster graphics support available.
- value
- value
AI-assisted analysis of tui-cs/Terminal.Gui@2e47b11478 (2026-08-13).
Data as JSON: /api/errors/65ee9f5d710d0849.
Report an issue: GitHub.