{"record":{"id":"a93bba6960c57060","repo":"PaddlePaddle/PaddleOCR","slug":"scale-values-should-be-positive","errorCode":null,"errorMessage":"scale values should be positive","messagePattern":"scale values should be positive","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"ppocr/data/imaug/abinet_aug.py","lineNumber":107,"sourceCode":"        assert degrees >= 0, \"degree must be positive.\"\n        self.degrees = degrees\n\n        if translate is not None:\n            assert (\n                isinstance(translate, (tuple, list)) and len(translate) == 2\n            ), \"translate should be a list or tuple and it must be of length 2.\"\n            for t in translate:\n                if not (0.0 <= t <= 1.0):\n                    raise ValueError(\"translation values should be between 0 and 1\")\n        self.translate = translate\n\n        if scale is not None:\n            assert (\n                isinstance(scale, (tuple, list)) and len(scale) == 2\n            ), \"scale should be a list or tuple and it must be of length 2.\"\n            for s in scale:\n                if s <= 0:\n                    raise ValueError(\"scale values should be positive\")\n        self.scale = scale\n\n        if shear is not None:\n            if isinstance(shear, numbers.Number):\n                if shear < 0:\n                    raise ValueError(\n                        \"If shear is a single number, it must be positive.\"\n                    )\n                self.shear = [shear]\n            else:\n                assert isinstance(shear, (tuple, list)) and (\n                    len(shear) == 2\n                ), \"shear should be a list or tuple and it must be of length 2.\"\n                self.shear = shear\n        else:\n            self.shear = shear\n\n    def _get_inverse_affine_matrix(self, center, angle, translate, scale, shear):","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/ppocr/data/imaug/abinet_aug.py#L89-L125","documentation":"CVRandomAffine requires scale to be a 2-element tuple/list of positive scale factors; any element <= 0 raises ValueError at construction. Scale factors are multiplicative (1.0 = no scaling), so zero or negative magnitudes are meaningless for the random affine sampler.","triggerScenarios":"CVRandomAffine(degrees=10, scale=(0.5, 0)) or scale=(-1.0, 1.0); also passing scale=0 (a bare number fails the tuple/list assertion before this, but a list containing 0 hits this error).","commonSituations":"Typing scale=(0, 1.0) intending 'range from zero'; sign typos; porting configs where scale was expressed as percentages (e.g. (50, 150)) which are valid positive numbers but semantically wrong.","solutions":["Use two positive multiplicative factors, e.g. scale=(0.8, 1.2).","If expressing percentages, convert to fractions (50% -> 0.5).","Add a config sanity check that both elements are > 0 before training starts."],"exampleFix":"# before\nCVRandomAffine(degrees=10, scale=(0.5, 0))   # ValueError\n# after\nCVRandomAffine(degrees=10, scale=(0.8, 1.2))","handlingStrategy":"validation","validationCode":"def valid_scale(s) -> bool:\n    return (s is None\n            or (isinstance(s, (tuple, list)) and len(s) == 2\n                and all(x > 0 for x in s)))","typeGuard":"def is_valid_scale(v) -> bool:\n    return v is None or (isinstance(v, (tuple, list)) and len(v) == 2 and all(x > 0 for x in v))","tryCatchPattern":null,"preventionTips":["Treat scale as multiplicative factors around 1.0","Convert percentage-based configs to fractions before passing","Assert min < max and both > 0 in config validation"],"tags":["data-augmentation","abinet","affine","validation","valueerror"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}