{"record":{"id":"dc89d379420464ed","repo":"python/cpython","slug":"failed-to-encode-latin1-string-when-unpickling-a-t","errorCode":null,"errorMessage":"Failed to encode latin1 string when unpickling a time object. pickle.load(data, encoding='latin1') is assumed.","messagePattern":"Failed to encode latin1 string when unpickling a time object\\. pickle\\.load\\(data, encoding='latin1'\\) is assumed\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_pydatetime.py","lineNumber":1444,"sourceCode":"    def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0):\n        \"\"\"Constructor.\n\n        Arguments:\n\n        hour, minute (required)\n        second, microsecond (default to zero)\n        tzinfo (default to None)\n        fold (keyword only, default to zero)\n        \"\"\"\n        if (isinstance(hour, (bytes, str)) and len(hour) == 6 and\n            ord(hour[0:1])&0x7F < 24):\n            # Pickle support\n            if isinstance(hour, str):\n                try:\n                    hour = hour.encode('latin1')\n                except UnicodeEncodeError:\n                    # More informative error message.\n                    raise ValueError(\n                        \"Failed to encode latin1 string when unpickling \"\n                        \"a time object. \"\n                        \"pickle.load(data, encoding='latin1') is assumed.\")\n            self = object.__new__(cls)\n            self.__setstate(hour, minute or None)\n            self._hashcode = -1\n            return self\n        hour, minute, second, microsecond, fold = _check_time_fields(\n            hour, minute, second, microsecond, fold)\n        _check_tzinfo_arg(tzinfo)\n        self = object.__new__(cls)\n        self._hour = hour\n        self._minute = minute\n        self._second = second\n        self._microsecond = microsecond\n        self._tzinfo = tzinfo\n        self._hashcode = -1\n        self._fold = fold","sourceCodeStart":1426,"sourceCodeEnd":1462,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pydatetime.py#L1426-L1462","documentation":"Raised by time.__new__ during unpickling when the pickle payload's first argument is a 6-character str that cannot be encoded to latin1. Python pickles datetime.time as a byte string; when a pickle created with protocol-level str handling is loaded with an encoding other than latin1 (e.g. pickle.load(data, encoding='utf-8')), the str may contain non-latin1 characters and the reconstruction fails with this explanatory ValueError.","triggerScenarios":"pickle.loads(data, encoding='utf-8') (or pickle.load with a non-latin1 encoding) on a pickle containing a datetime.time; pickles produced by Python 2 and loaded into Python 3 with the wrong encoding argument; hand-crafted time('\\\\x89\\\\x00...') str arguments with chars above U+00FF.","commonSituations":"Migrating Python 2 pickle archives to Python 3 without the documented encoding='latin1' argument; cross-version data pipelines (Redis/database blob storage of pickles); loading old .pkl files with generic unpickle helpers that pass encoding='utf-8'.","solutions":["Load with pickle.load(f, encoding='latin1') as the message states","Re-serialize the data in a version-neutral format: JSON ISO strings, or pickle.dumps with the highest protocol in Python 3","If the source pickle is corrupt, recover field values and reconstruct time objects explicitly"],"exampleFix":"# before\nobj = pickle.load(f, encoding='utf-8')\n\n# after\nobj = pickle.load(f, encoding='latin1')","handlingStrategy":"try-catch","validationCode":"if isinstance(v, str) and any(ord(c) > 255 for c in v[:6]) and len(v) == 6:\n    raise ValueError('non-latin1 payload: load the pickle with encoding=latin1')","typeGuard":null,"tryCatchPattern":"try:\n    obj = pickle.load(f, encoding='latin1')\nexcept ValueError:\n    # payload is not a latin1 pickle; retry default or re-raise\n    raise","preventionTips":["Always pass encoding='latin1' when loading Python 2 str-era pickles","Migrate persisted pickles to protocol >= 4 or to JSON ISO strings","Never pickle datetime objects through version-mixed pipelines without a migration step"],"tags":["datetime","pickle","valueerror","python2-migration","encoding"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}