open-mmlab/mmdetection · error · ValueError

Invalid scale {scale}, must be positive.

Error message

Invalid scale {scale}, must be positive.

What it means

rescale_size() (backing imrescale and the Resize transform) computes the scale factor for resizing. When `scale` is a number it must be strictly positive; a value of 0 or a negative number is meaningless as a multiplicative scale and raises ValueError.

Source

Thrown at mmdet/datasets/transforms/transforms.py:82

                 return_scale: bool = False) -> tuple:
    """Calculate the new size to be rescaled to.

    Args:
        old_size (tuple[int]): The old size (w, h) of image.
        scale (float | tuple[int]): The scaling factor or maximum size.
            If it is a float number, then the image will be rescaled by this
            factor, else if it is a tuple of 2 integers, then the image will
            be rescaled as large as possible within the scale.
        return_scale (bool): Whether to return the scaling factor besides the
            rescaled image size.

    Returns:
        tuple[int]: The new rescaled image size.
    """
    w, h = old_size
    if isinstance(scale, (float, int)):
        if scale <= 0:
            raise ValueError(f'Invalid scale {scale}, must be positive.')
        scale_factor = scale
    elif isinstance(scale, tuple):
        max_long_edge = max(scale)
        max_short_edge = min(scale)
        scale_factor = min(max_long_edge / max(h, w),
                           max_short_edge / min(h, w))
    else:
        raise TypeError(
            f'Scale must be a number or tuple of int, but got {type(scale)}')
    # only change this
    new_size = _fixed_scale_size((w, h), scale_factor)

    if return_scale:
        return new_size, scale_factor
    else:
        return new_size

View on GitHub (pinned to cfd5d3a985)

Solutions

  1. Fix the scale value to a positive number (e.g. 1.0 to keep size, 0.5 to halve)
  2. If scale is computed, guard it: max(scale, eps) or assert scale > 0 before calling Resize/imrescale
  3. For absolute target sizes, pass a tuple like (1333, 800) instead of a numeric factor

Example fix

# before
dict(type='Resize', scale=0, keep_ratio=True)
# after
dict(type='Resize', scale=1.0, keep_ratio=True)
Defensive patterns

Strategy: validation

Validate before calling

assert isinstance(scale, (int, float)) and scale > 0, f'bad scale: {scale}'
# or clamp: scale = max(scale, 1e-6)

Type guard

def is_valid_scale(scale) -> bool:
    return isinstance(scale, (int, float)) and not isinstance(scale, bool) and scale > 0

Try / catch

try:
    img2 = mmcv.imrescale(img, scale)
except ValueError:
    raise ValueError(f'rescale scale must be > 0, got {scale}') from None

Prevention

When it happens

Trigger: Calling imrescale(img, scale) or configuring dict(type='Resize', scale=0) / scale=-1 / any float <= 0, including scale computed dynamically (e.g. scale_factor * 0) or a typo like scale=0.5 written as 0.

Common situations: Dynamically computed scale factors that evaluate to 0 (empty tensor, division producing 0); typos in config scale values; scale sourced from a variable that defaults to 0 before assignment.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27). Data as JSON: /api/errors/d12950d93194552e. Report an issue: GitHub.