pola-rs/polars · error · ValueError
`encoding` must be one of {'hex', 'base64'}, got {encoding!r
Error message
`encoding` must be one of {'hex', 'base64'}, got {encoding!r} What it means
Raised by `Expr.str.decode(encoding, strict=...)` when `encoding` is neither 'hex' nor 'base64'. Despite the name, this method only reverses binary-to-text transfer encodings — it is not a general character-set decoder like Python's `bytes.decode`. The check is a plain Python if/elif that falls through to ValueError.
Source
Thrown at py-polars/src/polars/expr/string.py:1433
>>> df.with_columns(pl.col("color").str.decode("hex").alias("decoded"))
shape: (3, 2)
┌────────┬─────────────────┐
│ color ┆ decoded │
│ --- ┆ --- │
│ str ┆ binary │
╞════════╪═════════════════╡
│ 000000 ┆ b"\x00\x00\x00" │
│ ffff00 ┆ b"\xff\xff\x00" │
│ 0000ff ┆ b"\x00\x00\xff" │
└────────┴─────────────────┘
"""
if encoding == "hex":
return wrap_expr(self._pyexpr.str_hex_decode(strict))
elif encoding == "base64":
return wrap_expr(self._pyexpr.str_base64_decode(strict))
else:
msg = f"`encoding` must be one of {{'hex', 'base64'}}, got {encoding!r}"
raise ValueError(msg)
def encode(self, encoding: TransferEncoding) -> Expr:
"""
Encode values using the provided encoding.
Parameters
----------
encoding : {'hex', 'base64'}
The encoding to use.
.. engine-support:: in-memory, streaming, distributed
Returns
-------
Expr
Expression of data type :class:`String`.
ExamplesView on GitHub (pinned to 5d8ebabf11)
Solutions
- Use 'hex' or 'base64' — these are the only supported encodings.
- For character-set decoding of binary data, use `map_elements` with Python's codecs, accepting the performance cost.
- If the decoded bytes are UTF-8 text, chain with a cast: decode to Binary then `.cast(pl.String)` via `map_elements(bytes.decode, ...)`.
- Double-check case: 'Hex' with a capital H is rejected.
Example fix
# before
pl.col("s").str.decode("utf-8")
# after
pl.col("s").str.decode("base64") # only 'hex' and 'base64' exist Defensive patterns
Strategy: validation
Validate before calling
TRANSFER_ENCODINGS = {"hex", "base64"}
if encoding not in TRANSFER_ENCODINGS:
raise ValueError(
f"str.decode supports only {sorted(TRANSFER_ENCODINGS)}, got {encoding!r}; "
"for charset decoding use map_elements with codecs"
)
out = pl.col(c).str.decode(encoding, strict=strict) Type guard
from typing import Literal, TypeGuard
TransferEncoding = Literal["hex", "base64"]
def is_transfer_encoding(x: object) -> TypeGuard[TransferEncoding]:
return isinstance(x, str) and x in ("hex", "base64") Prevention
- Remember str.decode output is Binary, not String — plan the next step of the pipeline accordingly.
- Keep codec names ('utf-8' etc.) out of str.decode/encode; those belong to map_elements with Python codecs.
- Validate encoding strings from config against the fixed set at load time.
When it happens
Trigger: `pl.col("s").str.decode("utf-8")`, `"ascii"`, `"latin-1"`, or a case variant like "Hex"; treating hex/base64-decoded output as text instead of `Binary` data.
Common situations: Developers assuming str.decode mirrors Python's codecs module; processing base64 blobs from APIs and reaching for the wrong encoding name; forgetting that the output is a Binary column that still needs further handling to become text.
Related errors
- string buffers must be converted
- cannot create String column without an offsets buffer
- offsets buffer must be cast from {polars_dtype} to Int64
- "pad_start" expects a `str`, given a {qualified_type_name(fi
- "pad_end" expects a `str`, given a {qualified_type_name(fill
AI-assisted analysis of pola-rs/polars@5d8ebabf11 (2026-08-19).
Data as JSON: /api/errors/3c1134d655637aad.
Report an issue: GitHub.