pola-rs/polars · error · ValueError
Can't patch loop of type %s
Error message
Can't patch loop of type %s
What it means
To run async drivers synchronously, polars patches the current event loop with vendored nest_asyncio, which requires an asyncio.BaseEventLoop subclass (it replaces run_forever/run_until_complete/_run_once and swaps _ready). C-implemented loops such as uvloop.Loop do not derive from BaseEventLoop, so apply() raises this ValueError naming the loop type.
Source
Thrown at py-polars/src/polars/_utils/nest_asyncio.py:392
try:
self._set_coroutine_origin_tracking(self._debug)
if self._asyncgens is not None:
sys.set_asyncgen_hooks(
firstiter=self._asyncgen_firstiter_hook,
finalizer=self._asyncgen_finalizer_hook,
)
yield
finally:
self._set_coroutine_origin_tracking(False)
if self._asyncgens is not None:
sys.set_asyncgen_hooks(*old_agen_hooks)
def _check_running(self):
"""Do not throw exception if loop is already running."""
pass
if not isinstance(loop, asyncio.BaseEventLoop):
raise ValueError("Can't patch loop of type %s" % type(loop))
if not isinstance(loop._ready, _ReentrantReady):
old_ready, loop._ready = loop._ready, _ReentrantReady()
while old_ready:
loop._ready.append(old_ready.popleft())
if hasattr(loop, "_nest_patched"):
return
cls = loop.__class__
cls.run_forever = run_forever
cls.run_until_complete = run_until_complete
cls._run_once = _run_once
cls._check_running = _check_running
cls._check_runnung = _check_running # typo in Python 3.7 source
cls._num_runs_pending = 1 if loop.is_running() else 0
cls._is_proactorloop = os.name == "nt" and issubclass(
cls, asyncio.ProactorEventLoop
)
if sys.version_info < (3, 7, 0):
cls._set_coroutine_origin_tracking = cls._set_coroutine_wrapperView on GitHub (pinned to df599052da)
Solutions
- Use a synchronous database driver/connection for read_database in that process
- Run the read in a subprocess or worker with the default policy: asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
- Await the async connector yourself and build the DataFrame (pl.from_arrow), avoiding the loop patch entirely
Example fix
# before uvloop.install() # app installed uvloop df = pl.read_database(qry, connection=conn) # ValueError: can't patch # after df = pl.read_database(qry, connection=sync_conn) # sync driver path
Defensive patterns
Strategy: type-guard
Validate before calling
import asyncio
loop = asyncio.get_event_loop()
if not isinstance(loop, asyncio.BaseEventLoop):
raise RuntimeError(f"cannot use async drivers with {type(loop).__name__}; use a sync driver") Type guard
import asyncio
def is_patchable_loop() -> bool:
try:
return isinstance(asyncio.get_event_loop(), asyncio.BaseEventLoop)
except RuntimeError:
return True # no running loop; a fresh default loop will be used Prevention
- Do not install uvloop in processes that call pl.read_database with async connectors
- Reset with asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy()) before such reads
- Prefer sync database drivers in uvloop-based services
When it happens
Trigger: pl.read_database(...) while uvloop is the active loop — installed explicitly via uvloop.install()/asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) or by a web framework (uvicorn, sanic) hosting the code that then calls polars.
Common situations: Async web services (uvloop is the default in many) that also call pl.read_database inline; test harnesses that install uvloop globally for speed.
Related errors
- Event loop stopped before Future completed.
- index positions should be smaller than 2^32
- index positions should be greater than or equal to -2^32
- negative stop is not supported for lazy slices
- Cannot set `iter_batches` for {self.driver_name} without als
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/0c710a3068712edb.
Report an issue: GitHub.