{"record":{"id":"a45cfd4646dde288","repo":"opendatalab/MinerU","slug":"invalid-scale-scale-must-be-positive","errorCode":null,"errorMessage":"Invalid scale {scale}, must be positive.","messagePattern":"Invalid scale (.+?), must be positive\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mineru/model/table/rec/unet_table/utils.py","lineNumber":317,"sourceCode":"def rescale_size(old_size, scale, return_scale=False):\n    \"\"\"Calculate the new size to be rescaled to.\n\n    Args:\n        old_size (tuple[int]): The old size (w, h) of image.\n        scale (float | tuple[int]): The scaling factor or maximum size.\n            If it is a float number, then the image will be rescaled by this\n            factor, else if it is a tuple of 2 integers, then the image will\n            be rescaled as large as possible within the scale.\n        return_scale (bool): Whether to return the scaling factor besides the\n            rescaled image size.\n\n    Returns:\n        tuple[int]: The new rescaled image size.\n    \"\"\"\n    w, h = old_size\n    if isinstance(scale, (float, int)):\n        if scale <= 0:\n            raise ValueError(f\"Invalid scale {scale}, must be positive.\")\n        scale_factor = scale\n    elif isinstance(scale, tuple):\n        max_long_edge = max(scale)\n        max_short_edge = min(scale)\n        scale_factor = min(max_long_edge / max(h, w), max_short_edge / min(h, w))\n    else:\n        raise TypeError(\n            f\"Scale must be a number or tuple of int, but got {type(scale)}\"\n        )\n\n    new_size = _scale_size((w, h), scale_factor)\n\n    if return_scale:\n        return new_size, scale_factor\n    else:\n        return new_size\n\n","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/model/table/rec/unet_table/utils.py#L299-L335","documentation":"Raised by rescale_size() (mmcv-derived helper inside mineru's UNet table recognizer) when the scale argument is a numeric value that is zero or negative. The function multiplies both image edges by this factor, so a non-positive factor is mathematically meaningless and would produce a zero-size image. It exists to fail fast before cv2/NumPy produce a cryptic downstream error.","triggerScenarios":"Calling rescale_size(old_size, scale) (or the table-rec pipeline that calls it, e.g. table structure preprocessing) with scale=0, a negative float, or a value computed from division that underflowed to 0, e.g. scale = target_px / max(h, w) when max(h, w) is huge or target_px is 0.","commonSituations":"Custom table-detection configs that pass a user-defined scale factor of 0 by mistake; dynamically computed ratios where the denominator is an image whose dimensions were read as 0 (corrupt image or failed load); copy-pasting a config where scale was meant to be a (short, long) tuple but only one element was supplied.","solutions":["Check the scale value passed to the table preprocessing config; it must be a positive float/int or a tuple like (736, 1280).","If scale is computed dynamically, guard the denominator: scale = target / max(max(h, w), 1).","Print/inspect the input image size right before the call; a (0, 0) size usually means the image failed to load earlier.","If you intended a max-size constraint, pass the tuple form (short_edge, long_edge) instead of a single factor."],"exampleFix":"// before\nnew_size = rescale_size(old_size, 0)  # scale typo / computed as 0\n\n// after\nnew_size = rescale_size(old_size, (736, 1280))  # tuple form, or a positive factor\nif isinstance(scale, (int, float)) and scale <= 0:\n    raise ValueError(f\"bad scale config: {scale}\")","handlingStrategy":"validation","validationCode":"def safe_scale(scale):\n    if isinstance(scale, (int, float)) and scale <= 0:\n        raise ValueError(f\"scale must be positive, got {scale}\")\n    return scale\n\nnew_size = rescale_size(size, safe_scale(cfg_scale))","typeGuard":"def is_valid_scale(s) -> bool:\n    return (isinstance(s, (int, float)) and s > 0) or (\n        isinstance(s, tuple) and len(s) == 2 and all(isinstance(v, int) for v in s)\n    )","tryCatchPattern":"try:\n    new_size = rescale_size(size, scale)\nexcept ValueError as e:\n    if \"must be positive\" in str(e):\n        scale = 1.0\n        new_size = rescale_size(size, scale)\n    else:\n        raise","preventionTips":["Validate scale factors in config loaders before pipeline startup","Guard dynamic ratios: divide by max(dim, 1)","Log the effective scale value once at init"],"tags":["table-recognition","image-resize","validation","valueerror"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}