Python Telegram Bot ConversationHandler Not Waiting for Response and Throwing NoneType Error on reply_text

I’m working on a Telegram bot using python-telegram-bot that downloads Reddit videos, processes them with moviepy, and asks users questions through a conversation flow. I’m running into two main problems:

Problem 1: Getting AttributeError: 'NoneType' object has no attribute 'reply_text' when trying to use update.message.reply_text("test")

Problem 2: The conversation handler doesn’t wait for user responses. Instead of pausing for input, it immediately moves to the next video processing cycle.

Here’s my conversation starter function:

async def begin_video_questions(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
    """Initiates conversation by uploading video and asking first question."""
    video_path = context.user_data.get('video_path')
    
    await context.bot.send_video(chat_id=update.effective_chat.id, video=open(video_path, 'rb'))
    await update.effective_message.reply_text("Which resolution do you prefer? (res1/res2)")
    
    return RESOLUTION

My main application setup:

if __name__ == '__main__':
    app = Application.builder().token('BOT_TOKEN').build()
    
    # Handler registration
    startup_handler = CommandHandler('start', startup)
    app.add_handler(startup_handler)
    app.add_handler(CallbackQueryHandler(callback_handler))

    conversation_handler = ConversationHandler(
        entry_points=[CommandHandler("start", begin_video_questions)],
        states={
            RESOLUTION: [MessageHandler(filters.TEXT & ~filters.COMMAND, resolution_handler)],
            DURATION: [MessageHandler(filters.TEXT & ~filters.COMMAND, duration_handler)],
            OVERLAY_COLOR: [MessageHandler(filters.TEXT & ~filters.COMMAND, overlay_color_handler)],
            OVERLAY_ALPHA: [MessageHandler(filters.TEXT & ~filters.COMMAND, overlay_alpha_handler)],
            VIDEO_TITLE: [MessageHandler(filters.TEXT & ~filters.COMMAND, video_title_handler)],
            TITLE_COLOR: [MessageHandler(filters.TEXT & ~filters.COMMAND, title_color_handler)],
            DESCRIPTION: [MessageHandler(filters.TEXT & ~filters.COMMAND, description_handler)],
        },
        fallbacks=[CommandHandler("stop", stop_conversation)],
    )
    
    app.add_handler(conversation_handler)
    app.run_polling(allowed_updates=Update.ALL_TYPES)

The function that calls the conversation starter:

async def handle_reddit_videos(update: Update, context: ContextTypes.DEFAULT_TYPE, username, url, video_count):
    while video_count < 3:
        for clip in video_list:
            await begin_video_questions(update, context)

My Questions:

  • What causes the NoneType error with reply_text?
  • Why does the bot skip user input and continue processing videos?

Any help would be great. Let me know if more code is needed.

You’re mixing manual function calls with ConversationHandler, which breaks everything. When you call begin_video_questions directly in a loop, you create multiple conversations at once and the state machine can’t handle it.

That NoneType error? It happens because update.message can be None for inline queries or edited messages. Use update.effective_message instead - it’s way more reliable.

Your real problem is that loop in handle_reddit_videos. ConversationHandler wants linear progression through states, but your while loop spawns competing conversation instances. Don’t do that.

Here’s the fix: move your video iteration logic into the conversation states. Store the video list and current index in context.user_data, then increment after each conversation finishes.

Also, you’ve got duplicate /start handlers - both startup and begin_video_questions are registered for the same command. Pick one. If you want conversations to start immediately, make ConversationHandler your primary /start handler.

I hit the same issue building my own Telegram bot with conversation flows. This is an architectural problem, not a syntax one. You’re calling begin_video_questions directly from handle_reddit_videos, which completely bypasses the conversation handler’s state management.

Conversation handlers need to be triggered through their entry points - you can’t just call them like regular functions. When you call begin_video_questions from your loop, it runs once but never actually enters the conversation state. That’s why it keeps processing videos instead of waiting for user input.

The NoneType error happens when update doesn’t have a message - usually with callback queries or different update types. Use update.effective_message instead of update.message everywhere.

Here’s what I’d do: let the conversation handler manage the video processing internally. Store your video queue in context.user_data and process one video per conversation cycle.

The problem is you’re calling begin_video_questions manually AND setting it as a conversation entry point. That’s creating conflicts. Plus your while loop runs before the conversation even starts - conversations are async state machines, not regular functions you can just call whenever you want. Drop the direct function call and let ConversationHandler trigger it properly through the /start command.