pypa/pip · error · TypeError
Cannot restore Marker from
Error message
Cannot restore Marker from {state!r} What it means
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'.
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.
Example fix
# before (fragile) import pickle m = pickle.loads(blob) # corrupted string # after (robust) from packaging.markers import Marker m = Marker(stored_marker_string)
Defensive patterns
Strategy: validation
Validate before calling
from packaging.markers import Marker
from packaging._tokenizer import ParserSyntaxError
def marker_string_reparses(s: str) -> bool:
try:
Marker(s)
except Exception:
return False
return True
Try / catch
import pickle
from packaging.markers import Marker
obj = pickle.loads(blob)
if not isinstance(obj, Marker):
# recreate from the stored string instead of trusting the pickle
...
Prevention
- Prefer storing the marker expression string and rebuilding via Marker(...) over persisting Marker pickles.
- Validate stored marker strings parse cleanly before pickling them.
When it happens
Trigger: 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.
Common situations: Loading pickled requirement/dependency objects across packaging versions; a serialization layer that rewrote or truncated the marker string before pickling.
Related errors
- Cannot restore Requirement from
- Cannot restore Specifier from
- Cannot restore SpecifierSet from
- Cannot restore Tag from
- Cannot restore Version from
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/5e9b4171bf9484c3.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/packaging/markers.py:468
def __eq__(self, other: object) -> bool:
if not isinstance(other, Marker):
return NotImplemented
return str(self) == str(other)
def __getstate__(self) -> str:
# Return the marker expression string for compactness and stability.
# Internal Node objects are excluded; the string is re-parsed on load.
return str(self)
def __setstate__(self, state: object) -> None:
if isinstance(state, str):
# New format (26.2+): just the marker expression string.
try:
self._markers = _normalize_extra_values(_parse_marker(state))
except ParserSyntaxError as exc:
raise TypeError(f"Cannot restore Marker from {state!r}") from exc
return
if isinstance(state, dict) and "_markers" in state:
# Old format (packaging <= 26.1, no __slots__): plain __dict__.
markers = state["_markers"]
if isinstance(markers, list):
self._markers = markers
return
if isinstance(state, tuple) and len(state) == 2:
# Old format (packaging <= 26.1, __slots__): (None, {slot: value}).
_, slot_dict = state
if isinstance(slot_dict, dict) and "_markers" in slot_dict:
markers = slot_dict["_markers"]
if isinstance(markers, list):
self._markers = markers
return
raise TypeError(f"Cannot restore Marker from {state!r}")
def __and__(self, other: Marker) -> Marker:View on GitHub (pinned to f399c37189)