can1357/oh-my-pi · error · RuntimeError
top-level await is not supported from synchronous magic exec
Error message
top-level await is not supported from synchronous magic execution
What it means
_await_sync drains a coroutine with asyncio.run for synchronous magic execution, but if called from inside a running event loop it refuses — asyncio.run cannot nest. It raises RuntimeError: top-level await is not supported from synchronous magic execution.
Source
Thrown at packages/coding-agent/src/eval/py/runner.py:1063
_install_builtins(_STATE.user_ns)
# ---------------------------------------------------------------------------
# Source execution (split last expression for rich display)
# ---------------------------------------------------------------------------
_TLA_FLAG = getattr(ast, "PyCF_ALLOW_TOP_LEVEL_AWAIT", 0x2000)
def _await_sync(coro) -> Any:
try:
running_loop = asyncio.get_running_loop()
except RuntimeError:
running_loop = None
if running_loop is not None and running_loop.is_running():
raise RuntimeError(
"top-level await is not supported from synchronous magic execution"
)
return asyncio.run(coro)
def _run_compiled_sync(code, ns: dict, *, want_value: bool) -> Any:
"""Synchronous execution path used by nested magic helpers."""
if code.co_flags & inspect.CO_COROUTINE:
result = _await_sync(eval(code, ns))
return result if want_value else None
if want_value:
return eval(code, ns)
exec(code, ns)
return None
async def _run_compiled_async(code, ns: dict, *, want_value: bool) -> Any:
"""Execute a code object in the persistent event loop.View on GitHub (pinned to 9690622007)
Solutions
- Use the async execution path for code containing top-level await
- Inside a running loop, await the coroutine directly instead of routing through the sync magic path
- Avoid calling sync-only magics from async contexts; rewrite the cell as async
- If you have a coroutine in sync code outside a loop, plain asyncio.run works — the error only fires inside a loop
Example fix
// before (inside async cell) result = %run fetch_data.py # magic returns coroutine, sync path -> error // after result = await run_async_flow()
Defensive patterns
Strategy: try-catch
Validate before calling
try:
asyncio.get_running_loop()
in_loop = True
except RuntimeError:
in_loop = False
# if in_loop, avoid sync magic paths with coroutines; await directly Try / catch
try:
result = run_magic_sync(...)
except RuntimeError as e:
if "top-level await" in str(e):
result = await run_magic_async(...) # switch to async path Prevention
- Inside async cells, await coroutines directly
- Do not call sync-only magics from within a running loop
- Keep async code on the async exec path end-to-end
When it happens
Trigger: Calling a magic (or sync-exec path) whose result is a coroutine while already inside a running loop — e.g. invoking %run / a magic from async cell code, or from async magic execution where a sync path is taken with a coroutine argument.
Common situations: Using await from within a sync magic, mixing sync and async exec paths, or an async function's coroutine reaching _run_compiled_sync via a magic.
Related errors
- Command aborted
- Command timed out
- Python kernel unavailable
- Python kernel unavailable
- Protocol paths are not supported by this helper: {path}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/10f7ea50cb85bffc.
Report an issue: GitHub.