pola-rs/polars · error · TypeError

LazyFrame is not subscriptable (aside from slicing) Use…

Error message

LazyFrame is not subscriptable (aside from slicing)

Use `select()` or `filter()` instead.

What it means

LazyFrame.__getitem__ only allows slices (row slicing), because a lazy plan cannot eagerly evaluate arbitrary column/row lookups. Any other subscript (integer, string column name, tuple) raises this TypeError. Polars directs you to the lazy-native equivalents select() and filter().

Solutions

  1. Use `lf.select('a')` instead of `lf['a']`
  2. Use `lf.filter(...)` predicates instead of row indexing
  3. Collect first if eager indexing is truly needed: `lf.collect()['a']`
  4. Row slicing is allowed: `lf[:10]` works

Example fix

// before
values = lf['a']

// after
values = lf.select('a')
# or, if eager access is required:
values = lf.collect()['a']
Defensive patterns

Strategy: type-guard

Validate before calling

if isinstance(df, pl.LazyFrame) and not isinstance(key, slice):
    df = df.select(key) if isinstance(key, str) else df.collect()[key]

Type guard

def is_lazy_subscriptable(key) -> bool:
    return isinstance(key, slice)

Try / catch

try:
    col = lf[key]
except TypeError as e:
    if "not subscriptable" in str(e):
        col = lf.select(key)
    else:
        raise

Prevention

When it happens

Trigger: `lf['a']`, `lf[0]`, `lf[:, 'a']`, `lf[0, 1]` — any non-slice index on a LazyFrame.

Common situations: Porting DataFrame indexing idioms to the lazy API; interactive exploration habits applied to lazy frames; dynamic column access in pipelines.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at py-polars/src/polars/lazyframe/frame.py:804

        │ 2   ┆ 5   │
        └─────┴─────┘
        >>> lf[::2].collect()
        shape: (2, 2)
        ┌─────┬─────┐
        │ a   ┆ b   │
        │ --- ┆ --- │
        │ i64 ┆ i64 │
        ╞═════╪═════╡
        │ 1   ┆ 4   │
        │ 3   ┆ 6   │
        └─────┴─────┘
        """
        if not isinstance(item, slice):
            msg = (
                "LazyFrame is not subscriptable (aside from slicing)"
                "\n\nUse `select()` or `filter()` instead."
            )
            raise TypeError(msg)
        return LazyPolarsSlice(self).apply(item)

    def __str__(self) -> str:
        return f"""\
naive plan: (run LazyFrame.explain(optimized=True) to see the optimized plan)

{self.explain(optimized=False)}\
"""

    def __repr__(self) -> str:
        # don't expose internal/private classpath
        return f"<{self.__class__.__name__} at 0x{id(self):X}>"

    def _repr_html_(self) -> str:
        try:
            dot = self._ldf.to_dot(optimized=False)
            svg = subprocess.check_output(
                ["dot", "-Nshape=box", "-Tsvg"], input=f"{dot}".encode()

View on GitHub (pinned to fe841f959e)