{"record":{"id":"620af847fdfec50e","repo":"python-telegram-bot/python-telegram-bot","slug":"file-filepath-name-does-not-contain-valid-pickle","errorCode":null,"errorMessage":"File {filepath.name} does not contain valid pickle data","messagePattern":"File (.+?) does not contain valid pickle data","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"critical","filePath":"src/telegram/ext/_picklepersistence.py","lineNumber":276,"sourceCode":"            self.user_data = {}\n            self.chat_data = {}\n            self.bot_data = self.context_types.bot_data()\n            self.callback_data = None\n        except pickle.UnpicklingError as exc:\n            filename = self.filepath.name\n            raise TypeError(f\"File {filename} does not contain valid pickle data\") from exc\n        except Exception as exc:\n            raise TypeError(f\"Something went wrong unpickling {self.filepath.name}\") from exc\n\n    def _load_file(self, filepath: Path) -> Any:\n        try:\n            with filepath.open(\"rb\") as file:\n                return _BotUnpickler(self.bot, file).load()\n\n        except OSError:\n            return None\n        except pickle.UnpicklingError as exc:\n            raise TypeError(f\"File {filepath.name} does not contain valid pickle data\") from exc\n        except Exception as exc:\n            raise TypeError(f\"Something went wrong unpickling {filepath.name}\") from exc\n\n    def _dump_singlefile(self) -> None:\n        data = {\n            \"conversations\": self.conversations,\n            \"user_data\": self.user_data,\n            \"chat_data\": self.chat_data,\n            \"bot_data\": self.bot_data,\n            \"callback_data\": self.callback_data,\n        }\n        with self.filepath.open(\"wb\") as file:\n            _BotPickler(self.bot, file, protocol=pickle.HIGHEST_PROTOCOL).dump(data)\n\n    def _dump_file(self, filepath: Path, data: object) -> None:\n        with filepath.open(\"wb\") as file:\n            _BotPickler(self.bot, file, protocol=pickle.HIGHEST_PROTOCOL).dump(data)\n","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/python-telegram-bot/python-telegram-bot/blob/d3b69d2e9fb7af6c796f84516cfda751752c7cb7/src/telegram/ext/_picklepersistence.py#L258-L294","documentation":"PicklePersistence with separate files (single_file=False) loads each section file (conversations, user_data, ...) via _load_file. If a section file exists but contains data that pickle rejects (UnpicklingError), TypeError with the file name is raised on first access to that data.","triggerScenarios":"PicklePersistence(filepath='mydata', single_file=False) with e.g. mydata_conversations present but not valid pickle — corrupted, truncated, or written by a different serializer.","commonSituations":"Same corruption scenarios as the single-file variant but per-section: one section file (often the largest, conversations) got truncated during a crash, or the directory was partially synced/copied.","solutions":["Identify the offending section from the file name in the message and delete/rename just that file to rebuild only that section","Restore the section file from backup","Use atomic writes (PicklePersistence's update_interval plus flush) or a custom Persistence writing via os.replace"],"exampleFix":"# before\npersistence = PicklePersistence(filepath='mydata', single_file=False)\n# mydata_conversations corrupt -> TypeError on get_conversations\n\n# after\nimport os\nos.rename('mydata_conversations', 'mydata_conversations.bak')\npersistence = PicklePersistence(filepath='mydata', single_file=False)","handlingStrategy":"validation","validationCode":"def check_section_files(base):\n    import glob\n    for f in glob.glob(base + '_*'):\n        try:\n            with open(f, 'rb') as fh:\n                pickle.load(fh)\n        except Exception:\n            os.rename(f, f + '.corrupt')","typeGuard":null,"tryCatchPattern":"try:\n    persistence.get_conversations()\nexcept TypeError as exc:\n    name = str(exc).split(\"'\")[0]  # parse file name from message\n    os.rename(name.strip(), name.strip() + '.corrupt')","preventionTips":["Use atomic writes (temp file + os.replace) in custom persistence","Monitor section file sizes; sudden zeros indicate truncation"],"tags":["python","telegram-bot","picklepersistence","pickle","data-corruption"],"backgroundTag":"corrupt-persistence-file","analyzedSha":"d3b69d2e9fb7af6c796f84516cfda751752c7cb7","analyzedAt":"2026-08-28T16:18:54.805Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}