{"record":{"id":"5e9b4171bf9484c3","repo":"pypa/pip","slug":"cannot-restore-marker-from-state-r","errorCode":null,"errorMessage":"Cannot restore Marker from {state!r}","messagePattern":"Cannot restore Marker from (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/markers.py","lineNumber":468,"sourceCode":"\n    def __eq__(self, other: object) -> bool:\n        if not isinstance(other, Marker):\n            return NotImplemented\n\n        return str(self) == str(other)\n\n    def __getstate__(self) -> str:\n        # Return the marker expression string for compactness and stability.\n        # Internal Node objects are excluded; the string is re-parsed on load.\n        return str(self)\n\n    def __setstate__(self, state: object) -> None:\n        if isinstance(state, str):\n            # New format (26.2+): just the marker expression string.\n            try:\n                self._markers = _normalize_extra_values(_parse_marker(state))\n            except ParserSyntaxError as exc:\n                raise TypeError(f\"Cannot restore Marker from {state!r}\") from exc\n            return\n        if isinstance(state, dict) and \"_markers\" in state:\n            # Old format (packaging <= 26.1, no __slots__): plain __dict__.\n            markers = state[\"_markers\"]\n            if isinstance(markers, list):\n                self._markers = markers\n                return\n        if isinstance(state, tuple) and len(state) == 2:\n            # Old format (packaging <= 26.1, __slots__): (None, {slot: value}).\n            _, slot_dict = state\n            if isinstance(slot_dict, dict) and \"_markers\" in slot_dict:\n                markers = slot_dict[\"_markers\"]\n                if isinstance(markers, list):\n                    self._markers = markers\n                    return\n        raise TypeError(f\"Cannot restore Marker from {state!r}\")\n\n    def __and__(self, other: Marker) -> Marker:","sourceCodeStart":450,"sourceCodeEnd":486,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/markers.py#L450-L486","documentation":"Raised by Marker.__setstate__ (markers.py:466-468) for the stable 26.2+ pickle format where state is the marker expression string. If that string cannot be re-parsed by _parse_marker (ParserSyntaxError), unpickling raises TypeError('Cannot restore Marker from ...'). The original parse error is chained via 'from exc'.","triggerScenarios":"Unpickling a Marker whose stored expression string is malformed — e.g. a hand-crafted pickle, a string corrupted in transit/storage, or a marker string valid under an older packaging grammar that the current parser rejects.","commonSituations":"Loading pickled requirement/dependency objects across packaging versions; a serialization layer that rewrote or truncated the marker string before pickling.","solutions":["Do not rely on long-lived Marker pickles; store the marker string and rebuild with Marker(...) on load.","Recreate the pickle with the current packaging version."],"exampleFix":"# before (fragile)\nimport pickle\nm = pickle.loads(blob)  # corrupted string\n# after (robust)\nfrom packaging.markers import Marker\nm = Marker(stored_marker_string)","handlingStrategy":"validation","validationCode":"from packaging.markers import Marker\nfrom packaging._tokenizer import ParserSyntaxError\n\ndef marker_string_reparses(s: str) -> bool:\n    try:\n        Marker(s)\n    except Exception:\n        return False\n    return True\n","typeGuard":null,"tryCatchPattern":"import pickle\nfrom packaging.markers import Marker\n\nobj = pickle.loads(blob)\nif not isinstance(obj, Marker):\n    # recreate from the stored string instead of trusting the pickle\n    ...\n","preventionTips":["Prefer storing the marker expression string and rebuilding via Marker(...) over persisting Marker pickles.","Validate stored marker strings parse cleanly before pickling them."],"tags":["pickle","markers","serialization"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}