{"record":{"id":"13be0baccc823a27","repo":"opendatalab/MinerU","slug":"scale-must-be-a-number-or-tuple-of-int-but-got-t","errorCode":null,"errorMessage":"Scale must be a number or tuple of int, but got {type(scale)}","messagePattern":"Scale must be a number or tuple of int, but got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"mineru/model/table/rec/unet_table/utils.py","lineNumber":324,"sourceCode":"            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\ndef _scale_size(size, scale):\n    \"\"\"Rescale a size by a ratio.\n\n    Args:\n        size (tuple[int]): (w, h).\n        scale (float | tuple(float)): Scaling factor.\n","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/model/table/rec/unet_table/utils.py#L306-L342","documentation":"Raised by rescale_size() in mineru's UNet table utilities when the scale argument is neither a number nor a tuple. The function's contract is scale: float | int | tuple[int, int]; anything else (str, list, None, dict) hits the else branch and this TypeError. It mirrors mmcv's mmcv.image.rescale_size behavior.","triggerScenarios":"Passing scale as a string ('0.5') read from YAML/JSON config without conversion; passing a list [736, 1280] instead of a tuple; passing None because a config key was missing; passing a numpy scalar type not registered as float/int.","commonSituations":"Configs loaded from YAML where the scale entry is quoted; JSON configs that naturally produce lists; None propagation from an optional pipeline argument that was never defaulted.","solutions":["Convert the config value before calling: scale = tuple(scale) if isinstance(scale, list) else float(scale) as appropriate.","Default missing optional scale config keys instead of letting None flow into the call.","If using numpy types, cast with float(scale) before passing."],"exampleFix":"# before\nnew_size = rescale_size(size, cfg[\"scale\"])  # cfg has scale: \"0.5\" or [736, 1280]\n\n# after\nraw = cfg[\"scale\"]\nscale = tuple(raw) if isinstance(raw, list) else (float(raw) if isinstance(raw, str) else raw)\nnew_size = rescale_size(size, scale)","handlingStrategy":"type-guard","validationCode":"raw = cfg.get(\"scale\")\nscale = tuple(raw) if isinstance(raw, list) else (float(raw) if isinstance(raw, str) else raw)\nassert isinstance(scale, (int, float, tuple)), f\"bad scale type: {type(scale)}\"","typeGuard":"from numbers import Number\n\ndef is_valid_scale_type(s) -> bool:\n    return isinstance(s, Number) or (isinstance(s, tuple) and len(s) == 2)","tryCatchPattern":"try:\n    new_size = rescale_size(size, scale)\nexcept TypeError as e:\n    raise TypeError(f\"config scale {scale!r} invalid: {e}\") from e","preventionTips":["Normalize config values (str->float, list->tuple) at load time","Default optional scale keys explicitly","Add schema validation for pipeline configs"],"tags":["table-recognition","image-resize","typeerror","type-validation"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}