{"record":{"id":"4c7c3b23906512fe","repo":"jumpserver/jumpserver","slug":"code-error","errorCode":null,"errorMessage":"Code error","messagePattern":"Code error","errorType":"exception","errorClass":"CodeError","httpStatus":null,"severity":"warning","filePath":"apps/common/utils/verify_code.py","lineNumber":65,"sourceCode":"\n        return self.gen_and_send()\n\n    def gen_and_send(self):\n        try:\n            if not self.code:\n                self.code = self.__generate()\n            self.__send(self.code)\n        except JMSException:\n            self.__clear()\n            raise\n\n    def verify(self, code):\n        right = cache.get(self.key)\n        if not right:\n            raise CodeExpired\n\n        if right != code:\n            raise CodeError\n\n        self.__clear()\n        return True\n\n    def __clear(self):\n        cache.delete(self.key)\n\n    def __ttl(self):\n        return cache.ttl(self.key)\n\n    def __get_code(self):\n        return cache.get(self.key)\n\n    def __generate(self):\n        code = random_string(settings.SMS_CODE_LENGTH, lower=False, upper=False)\n        self.code = code\n        return code\n","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/jumpserver/jumpserver/blob/6ec464fabd61b95912d539455a3a5f15f5c59fe0/apps/common/utils/verify_code.py#L47-L83","documentation":"VerifyCode.verify() in apps/common/utils/verify_code.py compares the submitted value against the cached expected code; a mismatch raises CodeError. This is the wrong-code path — the key exists (not expired) but right != code, i.e. the user typed/received a different value.","triggerScenarios":"User mistypes the digits; multiple codes requested and the user enters an older one (only the latest is cached); SMS body mangled or truncated by the carrier; frontend sends the code with whitespace or concatenated fields.","commonSituations":"Typing errors on mobile; stale code from an earlier send still visible in the SMS app; template issues dropping digits; testing with hardcoded wrong values.","solutions":["Trim/normalize the input before verify: verify(user_input.strip())","When resending, inform the user the newest SMS is authoritative (older codes are overwritten in cache)","Catch CodeError and show a retry prompt without revealing which part failed; rate-limit verification attempts to prevent brute force","Check the SMS template renders the full code with no truncation"],"exampleFix":"# before\nverify_code.verify(code)\n# after\nfrom apps.common.utils.verify_code import CodeError\ntry:\n    verify_code.verify(code.strip())\nexcept CodeError:\n    return error_response('Incorrect verification code')","handlingStrategy":"validation","validationCode":"import re\n\ndef normalize_code(raw) -> bool:\n    return bool(re.fullmatch(r'\\d{4,8}', raw.strip()))\n\nif not normalize_code(user_input):\n    return error_response('Enter the digits from the SMS')\nverify_code.verify(user_input.strip())","typeGuard":"def is_plausible_code(value) -> bool:\n    import re\n    return isinstance(value, str) and bool(re.fullmatch(r'\\d{4,8}', value.strip()))","tryCatchPattern":"from apps.common.utils.verify_code import CodeError\ntry:\n    verify_code.verify(user_input.strip())\nexcept CodeError:\n    attempts += 1\n    if attempts >= MAX_ATTEMPTS:\n        lock_session()\n    return error_response('Incorrect code')","preventionTips":["Strip whitespace and enforce digit format before verify","Tell users to use the latest SMS after a resend","Rate-limit verify attempts to block brute force"],"tags":["python","verification-code","input-mismatch"],"backgroundTag":"verification-code-mismatch","analyzedSha":"6ec464fabd61b95912d539455a3a5f15f5c59fe0","analyzedAt":"2026-08-28T11:33:00.925Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}