pola-rs/polars · error · NotImplementedError
`sink_csv` is not supported by {type(self).__name__}
Error message
`sink_csv` is not supported by {type(self).__name__} What it means
`Engine.sink_csv` (engine.py:306) is the optional `Engine` hook behind `LazyFrame.sink_csv`. Its default stub raises `NotImplementedError` naming the engine. All built-in engines implement it (locally, or remotely via Polars Cloud with a restricted option set), so in practice only custom `Engine` subclasses missing the override trigger it.
Source
Thrown at py-polars/src/polars/lazyframe/engine.py:306
date_format: str | None,
time_format: str | None,
float_scientific: bool | None,
float_precision: int | None,
decimal_comma: bool,
null_value: str | None,
quote_style: CsvQuoteStyle | None,
maintain_order: bool,
storage_options: StorageOptionsDict | None,
credential_provider: CredentialProviderFunction | Literal["auto"] | None,
retries: int | None,
sync_on_close: SyncOnCloseMethod | None,
mkdir: bool,
lazy: bool,
optimizations: QueryOptFlags,
) -> LazyFrame | None:
"""See :meth:`polars.LazyFrame.sink_csv`."""
msg = f"`sink_csv` is not supported by {type(self).__name__}"
raise NotImplementedError(msg)
def sink_ndjson(
self,
lf: LazyFrame,
path: str | Path | IO[bytes] | IO[str] | PartitionBy,
*,
compression: Literal["uncompressed", "gzip", "zstd"],
compression_level: int | None,
check_extension: bool,
maintain_order: bool,
storage_options: StorageOptionsDict | None,
credential_provider: CredentialProviderFunction | Literal["auto"] | None,
retries: int | None,
sync_on_close: SyncOnCloseMethod | None,
mkdir: bool,
lazy: bool,
optimizations: QueryOptFlags,
) -> LazyFrame | None:View on GitHub (pinned to df599052da)
Solutions
- Use a built-in engine: `lf.sink_csv(path, engine='streaming')` (default), or `engine=pl.RemoteEngine()` with only the supported options
- Implement `sink_csv` on your `Engine` subclass with the stub's full keyword signature
- Stopgap: `lf.collect().write_csv(path)`
- Detect the missing capability before calling when engines are pluggable
Example fix
# before
lf.sink_csv('out.csv', engine=my_custom_engine) # NotImplementedError
# after
lf.sink_csv('out.csv', engine='streaming')
# or implement `sink_csv` on MyEngine Defensive patterns
Strategy: validation
Validate before calling
from polars.lazyframe.engine import Engine
def engine_can_sink_csv(engine: pl.Engine) -> bool:
return type(engine).sink_csv is not Engine.sink_csv
engine = my_engine if engine_can_sink_csv(my_engine) else pl.StreamingEngine() Try / catch
try:
lf.sink_csv(path, engine=my_engine)
except NotImplementedError as e:
if 'sink_csv' in str(e):
lf.collect().write_csv(path)
else:
raise Prevention
- Treat sinks as optional engine capabilities, not guaranteed API
- Centralize sink dispatch in one function with a documented fallback
- Cover all sink formats in engine conformance tests
When it happens
Trigger: `lf.sink_csv(path, engine=my_engine)` where `my_engine` is a custom `pl.Engine` subclass without `sink_csv`. Note that with `RemoteEngine` this method exists but rejects unsupported options with a different ValueError (see error 456).
Common situations: Custom backend development where CSV export is deferred; mocking engines in tests of export pipelines; switching a sink-heavy workload to a plugin engine before all sink formats are implemented.
Related errors
- `sink_parquet` is not supported by {type(self).__name__}
- `sink_ipc` is not supported by {type(self).__name__}
- `collect_async` is not supported by {type(self).__name__}
- `collect_batches` is not supported by {type(self).__name__}
- `collect_all` is not supported by {type(self).__name__}
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/a6d072fd6412fcea.
Report an issue: GitHub.