pola-rs/polars · error

invalid name: {n!r}

Error message

invalid name: {n!r}

What it means

Thrown inside cs.by_name (py-polars/src/polars/selectors.py:1291) when an ELEMENT inside a collection argument is not a string. by_name accepts str names and collections of str; a non-str element (int, None, float) inside a list/tuple hits this inner check and raises TypeError with the offending item's repr.

Source

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

    shape: (2, 2)
    ┌─────┬───────┐
    │ baz ┆ zap   │
    │ --- ┆ ---   │
    │ f64 ┆ bool  │
    ╞═════╪═══════╡
    │ 2.0 ┆ false │
    │ 5.5 ┆ true  │
    └─────┴───────┘
    """
    all_names = []
    for nm in names:
        if isinstance(nm, str):
            all_names.append(nm)
        elif isinstance(nm, Collection):
            for n in nm:
                if not isinstance(n, str):
                    msg = f"invalid name: {n!r}"
                    raise TypeError(msg)
                all_names.append(n)
        else:
            msg = f"invalid name: {nm!r}"
            raise TypeError(msg)

    return Selector._by_name(all_names, strict=require_all, expand_patterns=False)


def empty() -> Selector:
    """
    Select no columns.

    This is useful for composition with other selectors.

    See Also
    --------
    all : Select all columns in the current scope.

View on GitHub (pinned to df599052da)

Solutions

  1. Coerce all names to str before calling: cs.by_name([str(n) for n in names])
  2. Filter out non-names: [n for n in names if isinstance(n, str)] (note this silently drops columns — prefer explicit str() conversion if the values are the real names)
  3. Check the repr in the error to find the offending element and fix it at the source

Example fix

# before
sel = cs.by_name(["a", 1])

# after
sel = cs.by_name(["a", "1"])  # or
sel = cs.by_name([str(n) for n in ["a", 1]])
Defensive patterns

Strategy: validation

Validate before calling

names = [str(n) for n in candidate_names if n is not None]
sel = cs.by_name(names)

Type guard

from typing import TypeGuard

def all_str_names(items: list[object]) -> TypeGuard[list[str]]:
    return all(isinstance(n, str) for n in items)

Try / catch

try:
    sel = cs.by_name(names)
except TypeError as e:
    if "invalid name" in str(e):
        sel = cs.by_name([str(n) for n in names])
    else:
        raise

Prevention

When it happens

Trigger: cs.by_name(["a", 1]), cs.by_name(["a", None]), cs.by_name(["a", 1.0]). The collection itself is valid, but one member is not a str.

Common situations: Name lists built dynamically from mixed data — e.g. DataFrame column names that were renamed to ints, None placeholders for optional columns, or values from JSON that are numbers instead of strings.

Related errors


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