pola-rs/polars · error · TypeError
the remote engine can only sink to a URI or a `PartitionBy`,
Error message
the remote engine can only sink to a URI or a `PartitionBy`, got {qualified_type_name(path)!r} What it means
`RemoteEngine._sink_uri` (engine_remote.py:216) validates every remote sink target and only accepts a URI `str` or a `PartitionBy` object; anything else raises TypeError with the qualified type name. This is stricter than local sinks (which accept `Path`, file handles, and custom writers) because Polars Cloud workers write directly to cloud/object storage identified by URI — a local file object would make no sense remotely.
Source
Thrown at py-polars/src/polars/lazyframe/engine_remote.py:221
result.lazy(),
optimizations=optimizations,
background=background,
post_opt_callback=post_opt_callback,
)
# -- Sinks --------------------------------------------------------------------
@staticmethod
def _sink_uri(path: Any) -> str | PartitionBy:
"""Validate a Polars Cloud sink target."""
from polars.io.partition import PartitionBy
if not isinstance(path, (str, PartitionBy)):
msg = (
"the remote engine can only sink to a URI or a `PartitionBy`, got "
f"{qualified_type_name(path)!r}"
)
raise TypeError(msg)
return path
@staticmethod
def _reject_if_set(**kwargs: Any) -> None:
"""Reject options unsupported by Polars Cloud."""
for name, value in kwargs.items():
if value:
msg = f"`{name}` is not supported by the remote engine"
raise ValueError(msg)
def sink_parquet(
self,
lf: LazyFrame,
path: str | Path | IO[bytes] | PartitionBy,
*,
compression: ParquetCompression,
compression_level: int | None,
statistics: bool | str | dict[str, bool],View on GitHub (pinned to df599052da)
Solutions
- Pass the target as a URI string, e.g. `'s3://bucket/out.parquet'` (convert `Path` with `str(path)` only for local-URI sinks; cloud targets need a real scheme)
- For partitioned cloud output pass a `pl.PartitionBy(...)` target
- To keep output local, use a local engine (`engine='streaming'`) instead of RemoteEngine
- To bring results to this machine, use `lf.collect(engine=remote)` (warns about transfer) rather than a file-object sink
Example fix
# before
lf.sink_parquet(Path('out.parquet'), engine=remote) # TypeError
# after
lf.sink_parquet('s3://bucket/out.parquet', engine=remote)
# or keep it local:
lf.sink_parquet(Path('out.parquet'), engine='streaming') Defensive patterns
Strategy: type-guard
Validate before calling
from pathlib import Path
from polars.io.partition import PartitionBy
def is_remote_sink_target(path: object) -> bool:
return isinstance(path, str) or isinstance(path, PartitionBy)
def remote_target(path) -> str:
if isinstance(path, Path):
raise TypeError('convert local Path to a URI string or use a local engine')
if not is_remote_sink_target(path):
raise TypeError(f'remote sinks need a URI string, got {type(path).__name__}')
return path Type guard
from typing import TypeGuard
from polars.io.partition import PartitionBy
def is_remote_sink_target(path: object) -> TypeGuard[str | PartitionBy]:
return isinstance(path, (str, PartitionBy)) Try / catch
try:
lf.sink_parquet(target, engine=remote)
except TypeError as e:
if 'can only sink to a URI' in str(e):
lf.sink_parquet(str(target), engine=remote)
else:
raise Prevention
- Keep remote sinks on URI strings ('s3://...', 'abfs://...', 'gs://...')
- Convert Path objects to strings only for genuine URI schemes; local paths need a local engine
- Never hand file handles or custom writers to RemoteEngine sinks
When it happens
Trigger: `lf.sink_parquet(Path('out.parquet'), engine=remote)`, passing an `io.BytesIO`/opened file, or a custom writer object to any `sink_*` call on a RemoteEngine. Note `pathlib.Path` — fine locally — is rejected here because it is not a URI string.
Common situations: Code written against local sinks reused with a remote engine without changing the path argument; passing `Path` objects built by application logic; attempting to 'capture' remote output into a buffer locally.
Related errors
- `path` argument has invalid type {qualified_type_name(path)!
- `sink_ndjson` is not supported by {type(self).__name__}
- `sink_batches` is not supported by {type(self).__name__}
- `compat_level` has invalid type: {qualified_type_name(compat
- `{name}` is not supported by the remote engine
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/0be3eba2a8005a09.
Report an issue: GitHub.