pola-rs/polars · error · TypeError

cannot use NoopCatalog with

Error message

cannot use NoopCatalog with {fn_name}()

What it means

The Iceberg catalog resolved from the API parameter or environment defaulted to polars' NoopCatalog, which is a placeholder that performs no real catalog operations. polars raises TypeError because scan/sink functions like scan_iceberg or sink_iceberg cannot do anything useful without a functional catalog. This is a fail-fast guard raised from _from_api_parameter_or_environment_default.

Solutions

  1. Pass an explicit catalog argument to the API call (catalog='catalog_name' or a full URI).
  2. Set the catalog configuration in the environment (e.g. PYICEBERG_CATALOG__<name>__URI=...) or pyiceberg config so the default catalog resolves to a real implementation.
  3. Verify the catalog name matches one defined in your ~/.pyiceberg.yaml / .pyiceberg.yaml.

Example fix

// before
pl.scan_iceberg("db.table")  # no catalog configured -> NoopCatalog

// after
pl.scan_iceberg("db.table", catalog="my_catalog")  # or set PYICEBERG_CATALOG env config
Defensive patterns

Strategy: validation

Validate before calling

catalog = catalog or os.environ.get("PYICEBERG_CATALOG")
if not catalog or catalog_is_noop(catalog):
    raise ValueError("Configure a real Iceberg catalog before scanning")

Type guard

def is_usable_catalog(cfg: IcebergCatalogConfig) -> bool:
    return cfg.class_ is not NoopCatalog

Try / catch

try:
    df = pl.scan_iceberg(uri, catalog=cat).collect()
except TypeError as e:
    if "NoopCatalog" in str(e):
        df = pl.scan_iceberg(uri, catalog="default").collect()
    else:
        raise

Prevention

When it happens

Trigger: Calling an Iceberg API (e.g. scan_iceberg) without passing a catalog parameter while no valid catalog is configured in the environment, so IcebergCatalogConfig.from_catalog(default_catalog) resolves to class_ == NoopCatalog.

Common situations: Developers forget to set the catalog URI (e.g. PYICEBERG_CATALOG env var or polars.Config), or run in an environment where pyiceberg falls back to its default 'sql'/noop-style catalog; also happens when the catalog name passed does not match any configured catalog.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at py-polars/src/polars/io/iceberg/_dataset.py:198

                    )
                    if fn_name == "scan_iceberg"
                    else ""
                )

                msg = (
                    f"failed to load catalog for {fn_name}() ({error = }). "
                    "Configure the default PyIceberg catalog, or pass "
                    "a catalog via the 'catalog' parameter, or pass a PyIceberg "
                    "table object instead of the name."
                    f"{static_metadata_hint}"
                )
                raise ComputeError(msg) from error

            catalog_config = IcebergCatalogConfig.from_catalog(default_catalog)

        if catalog_config.class_ == NoopCatalog:
            msg = f"cannot use NoopCatalog with {fn_name}()"
            raise TypeError(msg)

        return catalog_config


@dataclass(kw_only=True)
class IcebergScanResolver:
    """
    Iceberg scan resolver.

    Defers scan resolution to run during IR resolution.
    """

    table: IcebergTableWrap
    snapshot_id: int | None
    from_snapshot_id_exclusive: int | None
    to_snapshot_id_inclusive: int | None
    reader_override: Literal["native", "pyiceberg"] | None
    use_metadata_statistics: bool

View on GitHub (pinned to fe841f959e)