{"record":{"id":"3f659c2561b245cd","repo":"pola-rs/polars","slug":"encoding-must-be-one-of-hex-base64-got-3f659c","errorCode":null,"errorMessage":"`encoding` must be one of {{'hex', 'base64'}}, got {encoding!r}","messagePattern":"`encoding` must be one of (.+?)\\}, got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/expr/string.py","lineNumber":1447,"sourceCode":"        >>> df.with_columns(pl.col(\"color\").str.decode(\"hex\").alias(\"decoded\"))\n        shape: (3, 2)\n        ┌────────┬─────────────────┐\n        │ color  ┆ decoded         │\n        │ ---    ┆ ---             │\n        │ str    ┆ binary          │\n        ╞════════╪═════════════════╡\n        │ 000000 ┆ b\"\\x00\\x00\\x00\" │\n        │ ffff00 ┆ b\"\\xff\\xff\\x00\" │\n        │ 0000ff ┆ b\"\\x00\\x00\\xff\" │\n        └────────┴─────────────────┘\n        \"\"\"\n        if encoding == \"hex\":\n            return wrap_expr(self._pyexpr.str_hex_decode(strict))\n        elif encoding == \"base64\":\n            return wrap_expr(self._pyexpr.str_base64_decode(strict))\n        else:\n            msg = f\"`encoding` must be one of {{'hex', 'base64'}}, got {encoding!r}\"\n            raise ValueError(msg)\n\n    def encode(self, encoding: TransferEncoding) -> Expr:\n        \"\"\"\n        Encode values using the provided encoding.\n\n        Parameters\n        ----------\n        encoding : {'hex', 'base64'}\n            The encoding to use.\n\n        .. engine-support:: in-memory, streaming, distributed\n\n        Returns\n        -------\n        Expr\n            Expression of data type :class:`String`.\n\n        Examples","sourceCodeStart":1429,"sourceCodeEnd":1465,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/expr/string.py#L1429-L1465","documentation":"Expr.str.decode is a transfer-encoding decoder limited to exactly 'hex' and 'base64'; the Python layer validates encoding before dispatch and raises ValueError for anything else. It is not a general text decoder — UTF-8/ASCII/latin-1 handling lives elsewhere (casting or UDFs), not in this namespace.","triggerScenarios":".str.decode('utf-8'), .str.decode('ascii'), .str.decode('Hex') (wrong case), .str.decode('hex ') (whitespace), or an encoding variable sourced from user input/config that was never validated.","commonSituations":"Assuming str.decode mirrors Python's bytes.decode; config- or CLI-driven encoding names; copy-paste from code that encoded with .str.encode('base64') but decoded with a text codec name; typos and case mismatches.","solutions":["Use 'hex' or 'base64' exactly (lowercase, no surrounding whitespace)","Normalize untrusted input up front: encoding = encoding.strip().lower() and validate against the allowed set","For text encodings, cast instead (.cast(pl.String) on binary data) or decode inside map_batches with a Python UDF"],"exampleFix":"# before\npl.col('raw').str.decode('utf-8')\n\n# after (hex/base64 payloads)\npl.col('raw').str.decode('base64')\n\n# for actual text decoding, cast:\npl.col('raw').cast(pl.String)","handlingStrategy":"validation","validationCode":"ALLOWED = {'hex', 'base64'}\nencoding = (encoding or '').strip().lower()\nif encoding not in ALLOWED:\n    raise ValueError(f'unsupported transfer encoding: {encoding!r}')\nout = df.select(pl.col('raw').str.decode(encoding))","typeGuard":"def is_transfer_encoding(x: object) -> bool:\n    return isinstance(x, str) and x in {'hex', 'base64'}","tryCatchPattern":"try:\n    expr = pl.col('raw').str.decode(encoding)\nexcept ValueError as e:\n    if 'must be one of' in str(e):\n        expr = pl.col('raw').str.decode('base64')  # chosen default\n    else:\n        raise","preventionTips":["Restrict encoding options at the config/CLI boundary with an enum of two values","Normalize case and whitespace before passing","Remember this API is transfer encoding only; text decoding goes through cast"],"tags":["polars","encoding","valueerror","string","binary"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}