sgl-project/sglang · error · ValueError

absolute aspect ratio must be smaller than 200, got {max(hei

Error message

absolute aspect ratio must be smaller than 200, got {max(height, width) / min(height, width)}

What it means

Raised by smart_resize in MiMo-V2 when, after the min-side upscale step, the image's aspect ratio (long side / short side) still exceeds 200. Such extreme panoramas would blow up the patch grid, so the resize algorithm rejects them outright.

Source

Thrown at python/sglang/srt/multimodal/processors/mimo_v2.py:1346

        seconds = int(timestamp % 60)
        return f"{minutes:02d}:{seconds:02d}"

    @staticmethod
    def smart_resize(
        height: int, width: int, factor: int, min_pixels: int, max_pixels: int
    ):
        """Rescales the image so that the following conditions are met:

        1. Both dimensions (height and width) are divisible by 'factor'.
        2. The total number of pixels is within the range ['min_pixels', 'max_pixels'].
        3. The aspect ratio of the image is maintained as closely as possible.
        """
        if min(height, width) < factor:
            scale = factor / min(height, width)
            height = int(round(height * scale))
            width = int(round(width * scale))
        elif max(height, width) / min(height, width) > 200:
            raise ValueError(
                f"absolute aspect ratio must be smaller than 200, got {max(height, width) / min(height, width)}"
            )
        h_bar = round(height / factor) * factor
        w_bar = round(width / factor) * factor
        if h_bar * w_bar > max_pixels:
            beta = math.sqrt((height * width) / max_pixels)
            h_bar = math.floor(height / beta / factor) * factor
            w_bar = math.floor(width / beta / factor) * factor
        elif h_bar * w_bar < min_pixels:
            beta = math.sqrt(min_pixels / (height * width))
            h_bar = math.ceil(height * beta / factor) * factor
            w_bar = math.ceil(width * beta / factor) * factor
        return int(h_bar), int(w_bar)

    @staticmethod
    def to_rgb(pil_image: Image.Image) -> Image.Image:
        if pil_image.mode == "RGBA":
            white_background = Image.new("RGB", pil_image.size, (255, 255, 255))

View on GitHub (pinned to 0132848349)

Solutions

  1. Reject or downscale extreme-aspect images client-side before sending (crop or tile the panorama)
  2. Center-crop the long side to bring the ratio under 200, or slice the strip into multiple images
  3. Add a pre-upload validation on image dimensions (max(long)/min(short) < 200)

Example fix

# before
im = Image.open('banner_20000x100.png'); proc.process_image(ImageInput(image=im))  # ValueError
# after
im = Image.open('banner_20000x100.png')
if max(im.size)/min(im.size) >= 200:
    w, h = im.size
    im = im.crop((0, 0, min(w, h*199), h))  # crop long side
proc.process_image(ImageInput(image=im))
Defensive patterns

Strategy: validation

Validate before calling

w, h = im.size
if min(w, h) == 0 or max(w, h) / min(w, h) >= 200:
    raise UserInputError(f'image aspect ratio {max(w,h)/min(w,h):.0f} too extreme; crop or tile first')

Type guard

def is_acceptable_aspect(im) -> bool:
    w, h = im.size
    return min(w, h) > 0 and max(w, h) / min(w, h) < 200

Try / catch

try:
    out = proc.process_image(image_input)
except ValueError as e:
    if 'aspect ratio' in str(e):
        return error_response(400, 'image too elongated; crop to aspect ratio < 200')
    raise

Prevention

When it happens

Trigger: Feeding an image whose width/height ratio (or height/width) is > 200 — e.g. a 20000x100 strip or a 50x20000 column — into process_image / get_visual_transform on a MiMo-V2 model.

Common situations: Panoramic banners, scan strips, or long screenshots sent as chat images; accidentally transposed dimensions; pathological/edge-case images in test corpora or adversarial inputs.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/37a25f294d360775. Report an issue: GitHub.