pola-rs/polars · error · TypeError

arr.to_struct() got a str instead of a list. hint: pass ['{f

Error message

arr.to_struct() got a str instead of a list. hint: pass ['{fields}'] instead of '{fields}'

What it means

TypeError raised by Expr.arr.to_struct when the fields argument is a plain string. Historically a string field-name template (e.g. 'field_n') was accepted; now fields must be a sequence of names or a FieldNaming callable, and polars explicitly hints to wrap the string in a list.

Source

Thrown at py-polars/src/polars/expr/array.py:1158

        shape: (5, 3)
        ┌──────┬──────┬──────┐
        │ x    ┆ y    ┆ z    │
        │ ---  ┆ ---  ┆ ---  │
        │ i64  ┆ i64  ┆ i64  │
        ╞══════╪══════╪══════╡
        │ 1    ┆ 0    ┆ 0    │
        │ 0    ┆ 1    ┆ 0    │
        │ 0    ┆ 0    ┆ 1    │
        │ null ┆ null ┆ null │
        │ null ┆ null ┆ null │
        └──────┴──────┴──────┘
        """
        if isinstance(fields, str):
            msg = (
                "arr.to_struct() got a str instead of a list. "
                f"hint: pass ['{fields}'] instead of '{fields}'"
            )
            raise TypeError(msg)

        pyexpr = self._pyexpr.arr_to_struct(fields)
        return wrap_expr(pyexpr)

    def shift(self, n: int | IntoExprColumn = 1) -> Expr:
        """
        Shift array values by the given number of indices.

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

        Parameters
        ----------
        n
            Number of indices to shift forward. If a negative value is passed, values
            are shifted in the opposite direction instead.

        Notes
        -----

View on GitHub (pinned to 68506541d2)

Solutions

  1. Wrap in a list: .arr.to_struct(['field_'])
  2. Or pass a naming callable like .arr.to_struct(lambda idx: f'f{idx}')
  3. Or omit fields entirely to use the default field_N naming

Example fix

# before
pl.col('lists').arr.to_struct('field_')
# after
pl.col('lists').arr.to_struct(['field_'])
Defensive patterns

Strategy: type-guard

Validate before calling

fields = [fields] if isinstance(fields, str) else fields

Type guard

def valid_fields(f) -> bool:
    import collections.abc as abc
    return callable(f) or (isinstance(f, abc.Sequence) and not isinstance(f, str))

Prevention

When it happens

Trigger: df.select(pl.col('a').arr.to_struct('field_')) — passing a str where a list of field names or callable is expected.

Common situations: Code written against older polars where a str template was valid; copy-paste from outdated Stack Overflow answers; intending a single custom name for one-element structs.

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@68506541d2 (2026-08-28). Data as JSON: /api/errors/e5f89c3c56cb0b78. Report an issue: GitHub.