Event Loop Conflict Error When Using Async Functions with python-telegram-bot Library

I’m working on a movie recommendation bot using the telegram bot library and async functions. When I try to start the bot, I keep getting this annoying error about the event loop already running. I also get another error saying it can’t close a running event loop.

I’m pretty new to async programming so maybe I’m doing something wrong. The problem happens when I call the polling method. Here’s what my code looks like:

import asyncio
from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, filters
from imdb import IMDb

async def start_bot():
    bot_app = ApplicationBuilder().token("MY_TOKEN_HERE").build()

    // Add command handlers
    bot_app.add_handler(CommandHandler("begin", start_command))
    bot_app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_genre))

    await bot_app.run_polling()  // Error happens here
    await bot_app.idle()

if __name__ == '__main__':
    asyncio.run(start_bot())

I think the issue is that asyncio.run creates its own loop but the telegram library also wants to use asyncio. I tried changing from start_polling to run_polling but same problem. I expected it to just work but it keeps complaining about multiple event loops.

Is there a different way to handle this? Should I not use asyncio.run or is there some other method that works better with telegram bots?

This is a common issue with the python-telegram-bot library. It runs its own event loop internally, and using asyncio.run() creates a conflict by trying to run two event loops simultaneously. I faced this challenge when I started using the library. The solution is quite straightforward: eliminate the asyncio.run() wrapper and remove async/await from your main function. The library manages the async operations internally, so you don’t need to deal with the event loop. Here’s a revised version of your code:

from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, filters

def main():
    bot_app = ApplicationBuilder().token("MY_TOKEN_HERE").build()
    
    bot_app.add_handler(CommandHandler("begin", start_command))
    bot_app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_genre))
    
    bot_app.run_polling()

if __name__ == '__main__':
    main()

This change resolves the event loop conflict, allowing run_polling() to handle everything for you.

The event loop conflict happens because asyncio.run() creates a new event loop while the telegram library wants to manage its own. I faced this issue when migrating from an older version.

Avoid removing async entirely—just use run_polling() without the async wrapper. Your handler functions can remain async if needed. Here’s a revised version of your code:

from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, filters

def start_bot():
    bot_app = ApplicationBuilder().token("MY_TOKEN_HERE").build()
    
    bot_app.add_handler(CommandHandler("begin", start_command))
    bot_app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_genre))
    
    bot_app.run_polling()

if __name__ == '__main__':
    start_bot()

Simply remove the asyncio.run() call entirely. The telegram library manages all async operations internally through run_polling(), which blocks until the bot stops.

yeah, same issue here last month! you’re mixing asyncio.run() with telegram’s event loop management. just ditch the asyncio wrapper and let run_polling() handle everything. don’t need await or async in main - the library does it all for u.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.