Python 3.14 compatibility: asyncio event loop error on bot startup #37

Open
opened 2026-04-04 03:31:23 +02:00 by shoko · 0 comments
Owner

Problem

Bot crashes on startup with Python 3.14:

RuntimeError: There is no current event loop in thread 'MainThread'.

Root Cause

In Python 3.10+, asyncio.get_event_loop() was deprecated in the main thread (it created one implicitly but with a warning). In Python 3.14, it now raises RuntimeError instead of creating one implicitly.

The telegram library's app.run_polling() internally calls asyncio.get_event_loop() to schedule async tasks, but in Python 3.14 there's no event loop in the main thread by default.

Current Fix (bot.py)

def main() -> None:
    import asyncio
    # ... token check ...
    try:
        asyncio.get_event_loop()
    except RuntimeError:
        asyncio.set_event_loop(asyncio.new_event_loop())
    app.run_polling(drop_pending_updates=True)

Better Fix (upstream)

Consider using asyncio.run() pattern instead:

async def main_async():
    app = build_app()
    app.post_init = post_init
    await app.initialize()
    await post_init(app)
    await app.start()
    await app.updater.start_polling(drop_pending_updates=True)
    # wait for stop signal
    await app.stop()

def main():
    asyncio.run(main_async())

This avoids the manual event loop management entirely and is the recommended pattern for modern asyncio code.

Status

  • Fix applied locally to apps/telegram-bot/bot.py
  • Bot starts successfully with Python 3.14 after fix
  • Not yet committed (pending review)

Labels

  • bug (python 3.14 compatibility)
  • telegram-bot
## Problem Bot crashes on startup with Python 3.14: ``` RuntimeError: There is no current event loop in thread 'MainThread'. ``` ## Root Cause In Python 3.10+, `asyncio.get_event_loop()` was deprecated in the main thread (it created one implicitly but with a warning). In **Python 3.14**, it now raises `RuntimeError` instead of creating one implicitly. The telegram library's `app.run_polling()` internally calls `asyncio.get_event_loop()` to schedule async tasks, but in Python 3.14 there's no event loop in the main thread by default. ## Current Fix (bot.py) ```python def main() -> None: import asyncio # ... token check ... try: asyncio.get_event_loop() except RuntimeError: asyncio.set_event_loop(asyncio.new_event_loop()) app.run_polling(drop_pending_updates=True) ``` ## Better Fix (upstream) Consider using `asyncio.run()` pattern instead: ```python async def main_async(): app = build_app() app.post_init = post_init await app.initialize() await post_init(app) await app.start() await app.updater.start_polling(drop_pending_updates=True) # wait for stop signal await app.stop() def main(): asyncio.run(main_async()) ``` This avoids the manual event loop management entirely and is the recommended pattern for modern asyncio code. ## Status - Fix applied locally to `apps/telegram-bot/bot.py` - Bot starts successfully with Python 3.14 after fix - Not yet committed (pending review) ## Labels - `bug` (python 3.14 compatibility) - `telegram-bot`
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: shoko/jigaido#37