{"record":{"id":"de28a7cb9b747063","repo":"pola-rs/polars","slug":"cannot-describe-a-lazyframe-that-has-no-columns","errorCode":null,"errorMessage":"cannot describe a LazyFrame that has no columns","messagePattern":"cannot describe a LazyFrame that has no columns","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/lazyframe/frame.py","lineNumber":1102,"sourceCode":"        │ null_count ┆ 0.0      ┆ 1.0      ┆ 0.0      ┆ 0    ┆ 0                   ┆ 0        │\n        │ mean       ┆ 2.266667 ┆ 45.0     ┆ 0.666667 ┆ null ┆ 2021-07-02 16:00:00 ┆ 16:07:10 │\n        │ std        ┆ 1.101514 ┆ 7.071068 ┆ null     ┆ null ┆ null                ┆ null     │\n        │ min        ┆ 1.0      ┆ 40.0     ┆ 0.0      ┆ xx   ┆ 2020-01-01          ┆ 10:20:30 │\n        │ 10%        ┆ 1.36     ┆ 41.0     ┆ null     ┆ null ┆ 2020-04-20          ┆ 11:13:34 │\n        │ 30%        ┆ 2.08     ┆ 43.0     ┆ null     ┆ null ┆ 2020-11-26          ┆ 12:59:42 │\n        │ 50%        ┆ 2.8      ┆ 45.0     ┆ null     ┆ null ┆ 2021-07-05          ┆ 14:45:50 │\n        │ 70%        ┆ 2.88     ┆ 47.0     ┆ null     ┆ null ┆ 2022-02-07          ┆ 18:09:34 │\n        │ 90%        ┆ 2.96     ┆ 49.0     ┆ null     ┆ null ┆ 2022-09-13          ┆ 21:33:18 │\n        │ max        ┆ 3.0      ┆ 50.0     ┆ 1.0      ┆ zz   ┆ 2022-12-31          ┆ 23:15:10 │\n        └────────────┴──────────┴──────────┴──────────┴──────┴─────────────────────┴──────────┘\n        \"\"\"  # noqa: W505\n        from polars.convert import from_dict\n\n        schema = self.collect_schema()\n\n        if not schema:\n            msg = \"cannot describe a LazyFrame that has no columns\"\n            raise TypeError(msg)\n\n        # create list of metrics\n        metrics = [\"count\", \"null_count\", \"mean\", \"std\", \"min\"]\n        if quantiles := parse_percentiles(percentiles):\n            metrics.extend(f\"{q * 100:g}%\" for q in quantiles)\n        metrics.append(\"max\")\n\n        @lru_cache\n        def skip_minmax(dt: PolarsDataType) -> bool:\n            return (\n                dt.is_nested()\n                or dt.is_extension()\n                or dt in (Categorical, Enum, Null, Object, Unknown)\n            )\n\n        # determine which columns will produce std/mean/percentile/etc\n        # statistics in a single pass over the frame schema\n        has_numeric_result, sort_cols = set(), set()","sourceCodeStart":1084,"sourceCodeEnd":1120,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/lazyframe/frame.py#L1084-L1120","documentation":"LazyFrame.describe() builds summary statistics per column, so it needs at least one column. If collect_schema() returns an empty schema (zero columns), polars raises TypeError rather than returning an empty table. This can only happen when the lazy plan itself selects zero columns, e.g. after select() of an empty list or reading an empty/edge-case source.","triggerScenarios":"lf.select([]).describe(); scanning a file whose schema resolution yields no columns; a pipeline step that drops all columns (e.g. select with a selector that matches nothing, like cs.numeric() on an all-string frame).","commonSituations":"Dynamic column selection with selectors that match zero columns; empty test fixtures; data files with unexpected schemas after an upstream change.","solutions":["Inspect lf.collect_schema().names() to see why the plan has no columns","Guard: if len(lf.collect_schema()) == 0, skip describe or fix the pipeline upstream","Fix the select()/selector logic so at least one column survives","If columns are chosen dynamically, fall back to a known column list when selection is empty"],"exampleFix":"# before\nstats = lf.select(cs.numeric()).describe()  # may have zero columns\n\n# after\nnum = cs.numeric()\nif len(lf.select(num).collect_schema()) > 0:\n    stats = lf.select(num).describe()\nelse:\n    stats = None","handlingStrategy":"validation","validationCode":"if len(lf.collect_schema().names()) == 0:\n    raise ValueError('pipeline produced a LazyFrame with no columns')\nstats = lf.describe()","typeGuard":"def has_columns(lf) -> bool:\n    return len(lf.collect_schema()) > 0","tryCatchPattern":"try:\n    stats = lf.describe()\nexcept TypeError:\n    stats = None  # or fix upstream column selection","preventionTips":["Assert non-empty schema right after dynamic select() calls","Log lf.collect_schema().names() at pipeline boundaries","Test selectors against representative schemas"],"tags":["polars","lazyframe","describe","schema"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}