Bug
chainlit run fails on Python 3.14. The browser shows a white page because
every static-asset request (/assets/*.js, /public/*) returns HTTP 500:
anyio.NoEventLoopError: Not currently running on any asynchronous event loop.
Available async backends: asyncio, trio
Root cause
chainlit/cli/__init__.py calls nest_asyncio.apply() at module import time.
nest_asyncio ≤ 1.6.0 patches loop.run_until_complete() via:
asyncio.ensure_future(future, loop=self) # nest_asyncio 1.6.0, line 88
The loop= keyword was deprecated in Python 3.8 and removed in Python 3.14
(bpo-39529). On Python 3.14 this silently
corrupts asyncio task registration: asyncio.current_task() returns None
inside running coroutines.
The failure chain:
chainlit run → import chainlit.cli → nest_asyncio.apply() at module level
nest_asyncio patches the loop using the removed loop= kwarg → tasks not registered
- Browser requests
/assets/index-*.js
FileResponse.__call__ → anyio.to_thread.run_sync(os.stat, path)
anyio → sniffio.current_async_library() → asyncio.current_task() → None
anyio.NoEventLoopError → HTTP 500 → no JS → white page
Note: nest_asyncio has not been updated since 2023 and is effectively
unmaintained.
Fix
Remove nest_asyncio entirely. asyncio.run(start()) at the bottom of
run_chainlit() is a top-level entry point — it does not run inside any other
event loop and has never needed re-entrant loop support. The existing comment
in the source ("Not sure if it is necessary...") confirms this was always
uncertain.
A PR with the fix, updated pyproject.toml, regenerated lockfile, and a
regression test is ready: #2953
Related
Bug
chainlit runfails on Python 3.14. The browser shows a white page becauseevery static-asset request (
/assets/*.js,/public/*) returns HTTP 500:Root cause
chainlit/cli/__init__.pycallsnest_asyncio.apply()at module import time.nest_asyncio≤ 1.6.0 patchesloop.run_until_complete()via:The
loop=keyword was deprecated in Python 3.8 and removed in Python 3.14(bpo-39529). On Python 3.14 this silently
corrupts asyncio task registration:
asyncio.current_task()returnsNoneinside running coroutines.
The failure chain:
chainlit run→import chainlit.cli→nest_asyncio.apply()at module levelnest_asynciopatches the loop using the removedloop=kwarg → tasks not registered/assets/index-*.jsFileResponse.__call__→anyio.to_thread.run_sync(os.stat, path)anyio→sniffio.current_async_library()→asyncio.current_task()→Noneanyio.NoEventLoopError→ HTTP 500 → no JS → white pageNote:
nest_asynciohas not been updated since 2023 and is effectivelyunmaintained.
Fix
Remove
nest_asyncioentirely.asyncio.run(start())at the bottom ofrun_chainlit()is a top-level entry point — it does not run inside any otherevent loop and has never needed re-entrant loop support. The existing comment
in the source ("Not sure if it is necessary...") confirms this was always
uncertain.
A PR with the fix, updated
pyproject.toml, regenerated lockfile, and aregression test is ready: #2953
Related
nest_asyncioloop=removal: https://bugs.python.org/issue39529