pola-rs/polars · error · ValueError
`format` must be one of {'binary', 'json'}, got {format!r}
Error message
`format` must be one of {'binary', 'json'}, got {format!r} What it means
Expr.deserialize supports exactly two formats: 'binary' (polars' compact self-describing format) and 'json'. Any other format string — 'pickle', 'arrow', or None where a string is expected — raises ValueError after the source is normalised but before a deserializer is chosen. Serialize and deserialize must use matching formats.
Source
Thrown at py-polars/src/polars/expr/expr.py:589
>>> expr = pl.col("foo").sum().over("bar")
>>> bytes = expr.meta.serialize()
>>> pl.Expr.deserialize(io.BytesIO(bytes))
<Expr ['col("foo").sum().over([col("ba…'] at ...>
"""
if isinstance(source, StringIO):
source = BytesIO(source.getvalue().encode())
elif isinstance(source, (str, Path)):
source = normalize_filepath(source)
elif isinstance(source, bytes):
source = BytesIO(source)
if format == "binary":
deserializer = PyExpr.deserialize_binary
elif format == "json":
deserializer = PyExpr.deserialize_json
else:
msg = f"`format` must be one of {{'binary', 'json'}}, got {format!r}"
raise ValueError(msg)
return cls._from_pyexpr(deserializer(source))
def to_physical(self) -> Expr:
"""
Cast to physical representation of the logical dtype.
- :func:`polars.datatypes.Date` -> :func:`polars.datatypes.Int32`
- :func:`polars.datatypes.Datetime` -> :func:`polars.datatypes.Int64`
- :func:`polars.datatypes.Time` -> :func:`polars.datatypes.Int64`
- :func:`polars.datatypes.Duration` -> :func:`polars.datatypes.Int64`
- :func:`polars.datatypes.Categorical` -> :func:`polars.datatypes.UInt32`
- `List(inner)` -> `List(physical of inner)`
- `Array(inner)` -> `Struct(physical of inner)`
- `Struct(fields)` -> `Array(physical of fields)`
Other data types will be left unchanged.
View on GitHub (pinned to df599052da)
Solutions
- Use 'binary' (compact default) or 'json' (debuggable) exactly
- Pair formats on both sides: expr.serialize(format='json') with pl.Expr.deserialize(src, format='json')
- If pickle is needed, pickle the produced bytes instead: pickle.dumps(expr.serialize())
Example fix
# before expr = pl.Expr.deserialize(data, format='pickle') # ValueError # after expr = pl.Expr.deserialize(data, format='binary') # round-trip: blob = expr.serialize(format='json'); expr = pl.Expr.deserialize(blob, format='json')
Defensive patterns
Strategy: validation
Validate before calling
VALID_FORMATS = ('binary', 'json')
if fmt not in VALID_FORMATS:
raise ValueError(f"format must be one of {VALID_FORMATS}")
expr = pl.Expr.deserialize(source, format=fmt) Type guard
from typing import Literal, TypeGuard
DeserializeFormat = Literal['binary', 'json']
def is_deserialize_format(v: str) -> TypeGuard[DeserializeFormat]:
return v in ('binary', 'json') Prevention
- Type the parameter Literal['binary','json']
- Always pair serialize/deserialize format arguments explicitly
- For pickle pipelines, pickle the bytes from expr.serialize() instead of asking deserialize for 'pickle'
When it happens
Trigger: pl.Expr.deserialize(source, format='pickle'); format=None on a code path that forwards it verbatim; typos like 'jsn' or 'JSON'.
Common situations: Caching serialised expressions inside pickle-based pipelines; interop code assuming pickle because other libraries default to it; format strings threaded through from config without validation.
Related errors
- input string does not contain DataFrame or Series
- `from_repr` does not support data type {dtype.base_type().__
- unhashable type: 'Expr' Consider hashing '{self}.meta'.
- the truth value of an Expr is ambiguous You probably got he
- Only call is implemented not {method}
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/51b3043256bc1c9d.
Report an issue: GitHub.