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

Expr.bin.decode supports exactly two transfer encodings, 'hex' and 'base64'; any other encoding string raises ValueError before dispatching to Rust. The comparison is exact and case-sensitive, and this namespace is for binary transfer encodings — not text/character decoding.

Source

Thrown at py-polars/src/polars/expr/binary.py:225

        ... )
        shape: (3, 3)
        ┌────────┬───────────┬─────────────────┐
        │ name   ┆ encoded   ┆ code            │
        │ ---    ┆ ---       ┆ ---             │
        │ str    ┆ binary    ┆ binary          │
        ╞════════╪═══════════╪═════════════════╡
        │ black  ┆ b"000000" ┆ b"\x00\x00\x00" │
        │ yellow ┆ b"ffff00" ┆ b"\xff\xff\x00" │
        │ blue   ┆ b"0000ff" ┆ b"\x00\x00\xff" │
        └────────┴───────────┴─────────────────┘
        """
        if encoding == "hex":
            return wrap_expr(self._pyexpr.bin_hex_decode(strict))
        elif encoding == "base64":
            return wrap_expr(self._pyexpr.bin_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:
        r"""
        Encode a value using the provided encoding.

        .. engine-support:: in-memory, streaming, distributed

        Parameters
        ----------
        encoding : {'hex', 'base64'}
            The encoding to use.

        Returns
        -------
        Expr
            Expression of data type :class:`Binary`.

        Examples

View on GitHub (pinned to df599052da)

Solutions

  1. Use exactly 'hex' or 'base64' (lowercase) for transfer decoding
  2. For text decoding, cast instead: pl.col('b').cast(pl.String) interprets bytes as UTF-8
  3. For other encodings, decode to bytes first and post-process with string operations

Example fix

# before
pl.col('b').bin.decode('utf8')  # ValueError

# after
pl.col('b').cast(pl.String)  # bytes -> UTF-8 text
pl.col('b').bin.decode('base64')  # valid transfer encoding
Defensive patterns

Strategy: validation

Validate before calling

if encoding not in {'hex', 'base64'}:
    raise ValueError("encoding must be 'hex' or 'base64'")
expr = pl.col('b').bin.decode(encoding)

Type guard

from typing import Literal, TypeGuard

TransferEncoding = Literal['hex', 'base64']

def is_transfer_encoding(v: str) -> TypeGuard[TransferEncoding]:
    return v in ('hex', 'base64')

Prevention

When it happens

Trigger: pl.col('b').bin.decode('utf8'), .bin.decode('base32'), or .bin.decode('HEX') — anything not exactly 'hex' or 'base64'.

Common situations: Confusing transfer encoding with character encoding (wanting pandas-style str.decode for text); typos; uppercase variants; expecting RFC 4648 base32/base64url support.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/77c8da079b322228. Report an issue: GitHub.