pola-rs/polars · error · TypeError

"pad_end" expects a `str`, given a {qualified_type_name(fill

Error message

"pad_end" expects a `str`, given a {qualified_type_name(fill_char)!r}

What it means

Raised in the Python layer of Expr.str.pad_end before execution: the fill_char argument must be a plain str. Any other type (int, bytes, None, an Expr) triggers a TypeError naming the qualified type. Padding is applied on the right side of the string; the fill character itself must be a literal single-character string.

Source

Thrown at py-polars/src/polars/expr/string.py:941

        >>> df.with_columns(padded=pl.col("a").str.pad_end(8, "*"))
        shape: (4, 2)
        ┌──────────────┬──────────────┐
        │ a            ┆ padded       │
        │ ---          ┆ ---          │
        │ str          ┆ str          │
        ╞══════════════╪══════════════╡
        │ cow          ┆ cow*****     │
        │ monkey       ┆ monkey**     │
        │ hippopotamus ┆ hippopotamus │
        │ null         ┆ null         │
        └──────────────┴──────────────┘
        """
        length_pyexpr = parse_into_expression(length)
        if not isinstance(fill_char, str):
            msg = (
                f'"pad_end" expects a `str`, given a {qualified_type_name(fill_char)!r}'
            )
            raise TypeError(msg)
        return wrap_expr(self._pyexpr.str_pad_end(length_pyexpr, fill_char))

    def zfill(self, length: int | IntoExprColumn) -> Expr:
        """
        Pad the start of the string with zeros until it reaches the given length.

        A sign prefix (`-`) is handled by inserting the padding after the sign
        character rather than before.

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

        Parameters
        ----------
        length
            Pad the string until it reaches this length. Strings with length equal to
            or greater than this value are returned as-is.

        See Also

View on GitHub (pinned to df599052da)

Solutions

  1. Pass fill_char as a str, e.g. fill_char='0' or fill_char='-'
  2. Convert values from config/data with str(value) before calling
  3. For right-aligned zero padding use .str.zfill(length) instead
  4. If the fill char must vary per row, preprocess via map_batches; the API does not support it

Example fix

# before
pl.col('code').str.pad_end(6, fill_char=0)

# after
pl.col('code').str.pad_end(6, fill_char='0')
# or for zero fill:
pl.col('code').str.zfill(6)
Defensive patterns

Strategy: type-guard

Validate before calling

fill_char = '-'
assert isinstance(fill_char, str), 'fill_char must be str'
expr = pl.col('s').str.pad_end(10, fill_char=fill_char)

Type guard

def is_valid_fill_char(x: object) -> bool:
    return isinstance(x, str) and len(x) >= 1

Prevention

When it happens

Trigger: Calling pl.col('s').str.pad_end(10, fill_char=0), fill_char=None, fill_char=b'-', or passing a column expression as fill_char (only length may be an expression; fill_char must be a literal str).

Common situations: Right-aligning numeric codes with '0' but passing the integer; bytes fill characters from serialized configs; None defaults from optional parameters; confusing the expression-accepting length parameter with the literal-only fill_char parameter.

Related errors


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