pola-rs/polars · error · TypeError
cannot sink to static Iceberg table
Error message
cannot sink to static Iceberg table: {type(target) = }, {getattr(target, 'catalog', None) = } What it means
The resolved catalog is pyiceberg's NoopCatalog, a catalog that performs no persistence. Sinking to such a table would silently discard data, so Polars raises TypeError identifying the target type and its catalog attribute.
Solutions
- Load the table from a real catalog (SQLCatalog, HiveCatalog, RESTCatalog, etc.) and sink to that
- Pass a table identifier string plus a configured catalog= argument instead of a NoopCatalog-backed Table
Example fix
// before
table = NoopCatalog('noop').load_table('db.t')
lf.sink_iceberg(table)
// after
catalog = load_catalog('prod', **props)
lf.sink_iceberg('db.t', catalog=catalog) Defensive patterns
Strategy: type-guard
Validate before calling
from pyiceberg.catalog.noop import NoopCatalog
if isinstance(target, Table) and isinstance(target.catalog, NoopCatalog):
raise TypeError('target table uses NoopCatalog; cannot sink') Type guard
def is_sinkable_table(target) -> bool:
from pyiceberg.catalog.noop import NoopCatalog
return not (hasattr(target, 'catalog') and isinstance(target.catalog, NoopCatalog)) Try / catch
try:
lf.sink_iceberg(target, catalog=catalog)
except TypeError as e:
if 'static Iceberg table' in str(e):
target = catalog.load_table(table_identifier)
lf.sink_iceberg(target, catalog=catalog)
else:
raise Prevention
- Never pass tables loaded from NoopCatalog to write operations
- Verify the catalog backend (REST/Hive/SQL) before sinking
- Use a string identifier plus catalog= argument in tests of real writes
When it happens
Trigger: Passing a pyiceberg Table loaded from NoopCatalog as target to sink_iceberg / IcebergSinkState.new, or constructing a table whose .catalog is a NoopCatalog (e.g. from pyiceberg static/test helpers).
Common situations: Testing code paths with NoopCatalog and then trying to write real data; loading a table via a catalog stub instead of Hive/REST/SQL catalog; forgetting to configure a real catalog.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- failed to load catalog for
- schema_mode='overwrite' is not supported for Iceberg tables…
- schema_mode='overwrite' is not supported for partitioned…
- schema_mode='overwrite' requires mode='overwrite'
- sink to Iceberg table with custom location provider
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/3ceb4f3581220cd3.
Report an issue: GitHub.
Appendix: source
Thrown at py-polars/src/polars/io/iceberg/_sink.py:548
)
if isinstance(target, str)
else (
IcebergCatalogConfig(
class_=type(target.catalog),
name=target.catalog.name,
properties=target.catalog.properties,
)
)
)
from pyiceberg.catalog.noop import NoopCatalog
if catalog_config.class_ is NoopCatalog:
msg = (
"cannot sink to static Iceberg table: "
f"{type(target) = }, {getattr(target, 'catalog', None) = }"
)
raise TypeError(msg)
return IcebergSinkState(
py_catalog_class_module=catalog_config.class_.__module__,
py_catalog_class_qualname=catalog_config.class_.__qualname__,
catalog_name=catalog_config.name,
catalog_properties=catalog_config.properties,
table_name=target if isinstance(target, str) else ".".join(target.name()),
mode=mode,
schema_mode=schema_mode,
snapshot_properties=snapshot_properties or {},
iceberg_storage_properties=storage_options or {},
compression=compression,
compression_level=compression_level,
row_group_size=row_group_size,
maintain_order=maintain_order,
sink_uuid_str=gen_uuid_v7().hex(),
table_=NoPickleOption(target if not isinstance(target, str) else None),
source_schema=None,View on GitHub (pinned to fe841f959e)