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
`LazyFrame.deserialize` (frame.py:495) reconstructs a `LazyFrame` from serialized plan bytes and dispatches on the `format` argument: `'binary'` maps to `PyLazyFrame.deserialize_binary` and `'json'` to `deserialize_json`. Any other value (pickle, serde, uppercase variants, typos) raises ValueError after the source has been normalized to a file path or `BytesIO` but before deserialization runs.
Source
Thrown at py-polars/src/polars/lazyframe/frame.py:495
│ i64 │
╞═════╡
│ 6 │
└─────┘
"""
if isinstance(source, StringIO):
source = BytesIO(source.getvalue().encode())
elif isinstance(source, (str, Path)):
source = normalize_filepath(source)
elif isinstance(source, bytes):
source = io.BytesIO(source)
if format == "binary":
deserializer = PyLazyFrame.deserialize_binary
elif format == "json":
deserializer = PyLazyFrame.deserialize_json
else:
msg = f"`format` must be one of {{'binary', 'json'}}, got {format!r}"
raise ValueError(msg)
return cls._from_pyldf(deserializer(source))
@property
def columns(self) -> list[str]:
"""
Get the column names.
Returns
-------
list of str
A list containing the name of each column in order.
Warnings
--------
Determining the column names of a LazyFrame requires resolving its schema,
which is a potentially expensive operation.
Using :meth:`collect_schema` is the idiomatic way of resolving the schema.View on GitHub (pinned to df599052da)
Solutions
- Use `'binary'` (default, compact) or `'json'` (exact lowercase) — and match the format used to serialize: `lf.serialize(format='json')` pairs with `deserialize(format='json')`
- If the format string is dynamic, validate it against `{'binary','json'}` before calling
- Store plans with `lf.serialize()` and rely on the default 'binary' to avoid mismatches
Example fix
# before lf2 = pl.LazyFrame.deserialize(data, format='pickle') # ValueError # after lf2 = pl.LazyFrame.deserialize(data, format='binary') # round-trip: pl.LazyFrame.deserialize(lf.serialize(format='json'), format='json')
Defensive patterns
Strategy: validation
Validate before calling
DESERIALIZE_FORMATS = frozenset({'binary', 'json'})
def deserialize_plan(data, fmt: str = 'binary') -> pl.LazyFrame:
if fmt not in DESERIALIZE_FORMATS:
raise ValueError(f'format must be one of {sorted(DESERIALIZE_FORMATS)}, got {fmt!r}')
return pl.LazyFrame.deserialize(data, format=fmt) Type guard
from typing import TypeGuard
def is_deserialize_format(value: object) -> TypeGuard[str]:
return value in ('binary', 'json') Try / catch
try:
lf = pl.LazyFrame.deserialize(data, format=fmt)
except ValueError as e:
if 'format' in str(e):
lf = pl.LazyFrame.deserialize(data, format='binary')
else:
raise Prevention
- Always serialize and deserialize with the same explicit format argument
- Persist the format next to the payload (e.g. {'format': 'json', 'plan': ...})
- Normalize case and strip whitespace on format strings coming from config
- Prefer the default 'binary' unless human-readable plans are required
When it happens
Trigger: `pl.LazyFrame.deserialize(data, format='pickle')`, `format='JSON'`, `format='json '` (whitespace), or any string not exactly `'binary'` or `'json'`. `data` itself may be `str`/`Path`/`bytes`/binary IO; only `format` is validated here.
Common situations: Hand-rolled persistence of query plans with a format field stored in a database; mixing up DataFrame serialization formats (`write_ipc`/feather) with LazyFrame plan formats; config-driven format parameters passed through unvalidated.
Related errors
- negative stop is not supported for lazy slices
- negative stride is not supported in conjunction with start+s
- the given slice {s!r} is not supported by lazy computation\n
- `format` must be one of {{'binary', 'json'}}, got {format!r}
- LazyFrame `how` must be one of {{{allowed}}}, got {how!r}
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/e012795cd4cc2ed8.
Report an issue: GitHub.