pola-rs/polars · error · TypeError

"pad_start" expects a `str`, given a

Error message

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

What it means

Expr.str.pad_start() requires `fill_char` to be exactly one str character; a non-string value (int, None, list, etc.) raises this TypeError naming the qualified type. Padding needs a character to fill with, so the type is checked in Python before the expression is built.

Solutions

  1. Pass a single-character string: fill_char='0'.
  2. Convert numeric fills: fill_char=str(0) — or simply write '0'.
  3. If the value may be missing, default it: fill_char or ' '.

Example fix

// before
pl.col('id').str.pad_start(10, 0)
// after
pl.col('id').str.pad_start(10, '0')
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(fill_char, str) or len(fill_char) != 1:
    raise ValueError('fill_char must be a single-character string')

Type guard

def is_fill_char(v) -> bool:
    return isinstance(v, str) and len(v) == 1

Try / catch

try:
    expr = pl.col('s').str.pad_start(n, fill_char)
except TypeError:
    expr = pl.col('s').str.pad_start(n, ' ')

Prevention

When it happens

Trigger: Calling Expr.str.pad_start(length, fill_char=0) or fill_char=None or fill_char=['*'].

Common situations: Passing a numeric pad character without quotes; getting None from an unset config default; padding with unicode chars supplied through variables of the wrong type.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/5596348c7bb9934f. Report an issue: GitHub.

Appendix: source

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

        --------
        >>> df = pl.DataFrame({"a": ["cow", "monkey", "hippopotamus", None]})
        >>> df.with_columns(padded=pl.col("a").str.pad_start(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_start" expects a `str`, given a {qualified_type_name(fill_char)!r}'
            raise TypeError(msg)
        return wrap_expr(self._pyexpr.str_pad_start(length_pyexpr, fill_char))

    def pad_end(self, length: int | IntoExprColumn, fill_char: str = " ") -> Expr:
        """
        Pad the end of the string until it reaches the given length.

        .. 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. Can be int or expression.
        fill_char
            The character to pad the string with.

        See Also
        --------

View on GitHub (pinned to fe841f959e)