pola-rs/polars · error · RuntimeError
{result}
Error message
{result} What it means
SurrealDBCursorProxy._unpack_result_async inspects the first response envelope of a SurrealDB query; if its 'status' field is anything other than 'OK' (e.g. 'ERR'), the server-side failure payload in response['result'] is re-raised as a RuntimeError. So the message text you see is SurrealDB's own error detail (syntax error, missing namespace/database, permissions), not polars wording. This is the async path used when read_database receives a surrealdb.SurrealDB (async) client.
Source
Thrown at py-polars/src/polars/io/database/_cursor_proxies.py:97
"""Cursor proxy for both SurrealDB and AsyncSurrealDB connections."""
_cached_result: list[dict[str, Any]] | None = None
def __init__(self, client: Any) -> None:
surrealdb = import_optional("surrealdb")
self.is_async = isinstance(client, surrealdb.AsyncSurrealDB)
self.execute_options: dict[str, Any] = {}
self.client = client
self.query: str = None # type: ignore[assignment]
@staticmethod
async def _unpack_result_async(
result: Coroutine[Any, Any, list[dict[str, Any]]],
) -> Coroutine[Any, Any, list[dict[str, Any]]]:
"""Unpack the async query result."""
response = (await result)[0]
if response["status"] != "OK":
raise RuntimeError(response["result"])
return response["result"]
@staticmethod
def _unpack_result(
result: list[dict[str, Any]],
) -> list[dict[str, Any]]:
"""Unpack the query result."""
response = result[0]
if response["status"] != "OK":
raise RuntimeError(response["result"])
return response["result"]
def close(self) -> None:
"""Close the cursor."""
# no-op; never close a user's Surreal session
def execute(self, query: str, **execute_options: Any) -> Self:
"""Execute a query (n/a: just store query for the fetch* methods)."""View on GitHub (pinned to df599052da)
Solutions
- Run the same query in the SurrealDB shell / Studio to see the full server error and fix the query
- Ensure the connection is established and a namespace + database are selected before read_database (await client.connect(); await client.use('ns', 'db'))
- Wrap the read in try/except RuntimeError and surface err.args[0] for logging, since the payload carries the actionable server message
Example fix
# before
await client.connect()
df = pl.read_database('SELECT * FROM orders', connection=client)
# after
await client.connect()
await client.use('prod', 'app')
df = pl.read_database('SELECT * FROM orders', connection=client) Defensive patterns
Strategy: try-catch
Try / catch
try:
df = pl.read_database(query, connection=async_client)
except RuntimeError as err:
detail = err.args[0] if err.args else ''
# SurrealDB payloads arrive here: parse/handle known cases
if 'was not found' in str(detail):
raise KeyError(f'table missing: {detail}') from err
raise Prevention
- Always connect() and use(namespace, database) before handing the client to read_database
- Validate SurrealQL by running it once in surreal CLI during development
- Treat RuntimeError from this path as a server message: log err.args[0] verbatim for debugging
When it happens
Trigger: pl.read_database(query='SELECT * FROM missing_table', connection=async_surreal_client) after client.connect(); invalid SurrealQL; querying before USE NS/DB or connect(); insufficient record-level permissions.
Common situations: Async FastAPI/asyncio services reading from SurrealDB; forgetting await client.use(namespace, database); typos in table names; version drift between the surrealdb python driver and server changing response envelopes.
Related errors
- Event loop stopped before Future completed.
- Can't patch loop of type %s
- `read_database` queries require at least {module_name} versi
- Cannot set `iter_batches` for {self.driver_name} without als
- Cannot set `iter_batches` without also setting a non-zero `b
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/1e0b70895fb6c560.
Report an issue: GitHub.