{"record":{"id":"53639f3f53adf57e","repo":"PaddlePaddle/PaddleOCR","slug":"degree-must-be-number-or-list-with-length-2","errorCode":null,"errorMessage":"degree must be number or list with length 2","messagePattern":"degree must be number or list with length 2","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"ppocr/data/imaug/abinet_aug.py","lineNumber":307,"sourceCode":"        cur_w, cur_h = self.base_w, self.base_h\n        scale_img = cv2.resize(img, (cur_w, cur_h), interpolation=get_interpolation())\n        for _ in range(self.factor):\n            scale_img = cv2.pyrDown(scale_img)\n        scale_img = cv2.resize(\n            scale_img, (src_w, src_h), interpolation=get_interpolation()\n        )\n        return scale_img\n\n\nclass CVGaussianNoise(object):\n    def __init__(self, mean=0, var=20):\n        self.mean = mean\n        if isinstance(var, numbers.Number):\n            self.var = max(int(sample_asym(var)), 1)\n        elif isinstance(var, (tuple, list)) and len(var) == 2:\n            self.var = int(sample_uniform(var[0], var[1]))\n        else:\n            raise Exception(\"degree must be number or list with length 2\")\n\n    def __call__(self, img):\n        noise = np.random.normal(self.mean, self.var**0.5, img.shape)\n        img = np.clip(img + noise, 0, 255).astype(np.uint8)\n        return img\n\n\nclass CVPossionNoise(object):\n    def __init__(self, lam=20):\n        self.lam = lam\n        if isinstance(lam, numbers.Number):\n            self.lam = max(int(sample_asym(lam)), 1)\n        elif isinstance(lam, (tuple, list)) and len(lam) == 2:\n            self.lam = int(sample_uniform(lam[0], lam[1]))\n        else:\n            raise Exception(\"lam must be number or list with length 2\")\n\n    def __call__(self, img):","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/ppocr/data/imaug/abinet_aug.py#L289-L325","documentation":"CVGaussianNoise's constructor validates var: a number is sampled via sample_asym, a 2-element tuple/list is sampled uniformly, and anything else raises Exception. The message says 'degree must be number or list with length 2', which is a copy-paste artifact — the failing parameter is `var`, the noise variance for np.random.normal.","triggerScenarios":"CVGaussianNoise(var=[10, 20, 30]) (length 3), var='20' (string from YAML), or var=None / dict.","commonSituations":"String-typed numbers from config files; confusion caused by the misleading 'degree' wording sending developers to inspect rotation params; three-element variance ranges.","solutions":["Pass var as a number (e.g. var=20) or exact 2-element sequence like var=(10, 30).","Cast config values: var=int(cfg['var']) for scalars.","Ignore the word 'degree' in the message — it is the noise variance that is malformed."],"exampleFix":"# before\nCVGaussianNoise(var=cfg['var'])            # cfg['var'] == '20' -> Exception\n# after\nCVGaussianNoise(var=float(cfg['var']) if not isinstance(cfg['var'], (list, tuple)) else tuple(cfg['var']))","handlingStrategy":"validation","validationCode":"import numbers\n\ndef valid_var(v) -> bool:\n    return (isinstance(v, numbers.Number)\n            or (isinstance(v, (tuple, list)) and len(v) == 2))","typeGuard":"import numbers\n\ndef is_valid_var(v) -> bool:\n    return isinstance(v, numbers.Number) or (isinstance(v, (tuple, list)) and len(v) == 2)","tryCatchPattern":null,"preventionTips":["The message says 'degree' but the parameter is var — check the variance argument","Cast config strings to float for scalar variances","Use exactly two bounds for sampled variance ranges"],"tags":["data-augmentation","abinet","noise","config","misleading-message","exception"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}