pola-rs/polars · error · TypeError

expected one or more `str`, `DataType` or selector; found

Error message

expected one or more `str`, `DataType` or selector; found {item!r} instead.

What it means

_combine_as_selector converts heterogeneous inputs (strings, dtypes, selectors, column Exprs) into one selector inside helpers like cs.exclude(). If an item is none of str, Polars DataType, Selector, or a Column, this TypeError is raised telling you what types are accepted.

Solutions

  1. Pass only column-name strings, Polars dtypes, selectors, or pl.col(...) expressions: cs.exclude('a', pl.Int64).
  2. Convert indices to names first: cs.exclude(df.columns[i] for i in idxs).
  3. Filter out None/invalid items before the call: cs.exclude(*(x for x in items if isinstance(x, str))).
  4. Use cs.all().exclude(...) style composition if mixing selectors and names.

Example fix

// before
cs.exclude([0, 1])
// after
cs.exclude(df.columns[0], df.columns[1])
Defensive patterns

Strategy: validation

Validate before calling

allowed = (str, pl.DataType, type(pl.Int64), pl.Expr)
bad = [x for x in items if not isinstance(x, allowed) and not hasattr(x, '_pyselector')]
if bad:
    raise ValueError(f"unsupported exclude items: {bad!r}")

Type guard

def is_selector_input(x) -> bool:
    import polars as pl
    from polars.selectors import is_selector
    return isinstance(x, (str, pl.Expr)) or is_selector(x) or getattr(getattr(x, '__module__', ''), 'startswith', lambda *_: False)('polars.datatypes')

Try / catch

try:
    sel = cs.exclude(*items)
except TypeError as e:
    if "expected one or more" in str(e):
        sel = cs.exclude(*filter(lambda x: isinstance(x, str), items))
    else:
        raise

Prevention

When it happens

Trigger: cs.exclude(123), cs.exclude(['a', None]), cs.exclude(some_dataframe), or passing nested lists / arbitrary Python objects into exclude() or any API that funnels through _combine_as_selector.

Common situations: Typos like passing a set of tuples, accidentally passing a DataFrame or Series, passing ints meant to be column indices (exclude takes names, not indices), or None sneaking in from an optional variable.

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/9a59d29e4b5b7455. Report an issue: GitHub.

Appendix: source

Thrown at py-polars/src/polars/selectors.py:308

            if isinstance(items, Collection) and not isinstance(items, str)
            else [items]
        ),
        *more_items,
    ):
        if is_selector(item):
            selectors.append(item)
        elif is_polars_dtype(item):
            dtypes.append(item)
        elif isinstance(item, str):
            if item.startswith("^") and item.endswith("$"):
                regexes.append(item)
            else:
                names.append(item)
        elif is_column(item):
            names.append(item.meta.output_name())  # type: ignore[union-attr]
        else:
            msg = f"expected one or more `str`, `DataType` or selector; found {item!r} instead."
            raise TypeError(msg)

    selected = []
    if names:
        selected.append(by_name(*names, require_all=False))
    if dtypes:
        selected.append(by_dtype(*dtypes))
    if regexes:
        selected.append(
            matches(
                "|".join(f"({rx})" for rx in regexes)
                if len(regexes) > 1
                else regexes[0]
            )
        )
    if selectors:
        selected.extend(selectors)

    return reduce(or_, selected)

View on GitHub (pinned to fe841f959e)