Skip to content

starting the bot with bootstrap_retries -1 fails startup #4966

@xmatthias

Description

@xmatthias

Steps to Reproduce

Use the below script with python-telegram-bot 22.4

import logging
import os

from telegram import Update
from telegram.ext import Application, ApplicationBuilder, CommandHandler, ContextTypes


LOGFORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
logging.basicConfig(
    level=logging.DEBUG,
    format=LOGFORMAT,
)

logger = logging.getLogger(__name__)
# logger.setLevel(logging.DEBUG)

token = os.environ.get('TELEGRAM_TOKEN')

# logger.debug("Creating telegram application")

application = Application.builder().token(token).build()


async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await context.bot.send_message(
        chat_id=update.effective_chat.id, text="I'm a bot, please talk to me!"
    )


start_handler = CommandHandler("start", start)
application.add_handler(start_handler)
application.run_polling(
    bootstrap_retries=-1,
)

The key is bootstrap_retries=-1 - which causes startup to be retried forever (even though the action already worked).

Expected behaviour

the application starts, /start responds with the expected response.

This worked with 22.3 - and fails with 22.4 - running into an endless loop.

Actual behaviour

Endless loop - of "This application is already initialized".
The bot doesn't respond to any command (it's never starting to poll)

Operating System

linux

Version of Python, python-telegram-bot & dependencies

python-telegram-bot 22.4 (2023.7-7837-g16117e5b6)
Bot API 9.2
Python 3.13.7 (main, Aug 28 2025, 17:07:40) [Clang 20.1.4 ]

Relevant log output

2025-09-21 08:56:28,844 - telegram.ext.ExtBot - DEBUG - Set Bot API URL: https://api.telegram.org/bot546065661:AAGSqjM2F3Zajs_HpiZY5LAYfD3AWmaGM3Y
2025-09-21 08:56:28,845 - telegram.ext.ExtBot - DEBUG - Set Bot API File URL: https://api.telegram.org/file/bot546065661:AAGSqjM2F3Zajs_HpiZY5LAYfD3AWmaGM3Y
2025-09-21 08:56:28,845 - __main__ - INFO - Starting polling
2025-09-21 08:56:28,845 - asyncio - DEBUG - Using selector: EpollSelector
2025-09-21 08:56:28,845 - telegram.ext - DEBUG - Network Retry Loop (Bootstrap Initialize Application): Starting
2025-09-21 08:56:28,845 - telegram.ext.ExtBot - DEBUG - Calling Bot API endpoint `getMe` with parameters `{}`
2025-09-21 08:56:28,848 - httpcore.connection - DEBUG - connect_tcp.started host='api.telegram.org' port=443 local_address=None timeout=5.0 socket_options=None
2025-09-21 08:56:28,886 - httpcore.connection - DEBUG - connect_tcp.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7f7f2397a510>
2025-09-21 08:56:28,887 - httpcore.connection - DEBUG - start_tls.started ssl_context=<ssl.SSLContext object at 0x7f7f23956210> server_hostname='api.telegram.org' timeout=5.0
2025-09-21 08:56:28,927 - httpcore.connection - DEBUG - start_tls.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7f7f23972490>
2025-09-21 08:56:28,927 - httpcore.http11 - DEBUG - send_request_headers.started request=<Request [b'POST']>
2025-09-21 08:56:28,928 - httpcore.http11 - DEBUG - send_request_headers.complete
2025-09-21 08:56:28,928 - httpcore.http11 - DEBUG - send_request_body.started request=<Request [b'POST']>
2025-09-21 08:56:28,928 - httpcore.http11 - DEBUG - send_request_body.complete
2025-09-21 08:56:28,928 - httpcore.http11 - DEBUG - receive_response_headers.started request=<Request [b'POST']>
2025-09-21 08:56:28,965 - httpcore.http11 - DEBUG - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Server', b'nginx/1.18.0'), (b'Date', b'Sun, 21 Sep 2025 06:56:28 GMT'), (b'Content-Type', b'application/json'), (b'Content-Length', b'261'), (b'Connection', b'keep-alive'), (b'Strict-Transport-Security', b'max-age=31536000; includeSubDomains; preload'), (b'Access-Control-Allow-Origin', b'*'), (b'Access-Control-Allow-Methods', b'GET, POST, OPTIONS'), (b'Access-Control-Expose-Headers', b'Content-Length,Content-Type,Date,Server,Connection')])
2025-09-21 08:56:28,966 - httpx - INFO - HTTP Request: POST https://api.telegram.org/bot546065661:AAGSqjM2F3Zajs_HpiZY5LAYfD3AWmaGM3Y/getMe "HTTP/1.1 200 OK"
2025-09-21 08:56:28,967 - httpcore.http11 - DEBUG - receive_response_body.started request=<Request [b'POST']>
2025-09-21 08:56:28,967 - httpcore.http11 - DEBUG - receive_response_body.complete
2025-09-21 08:56:28,967 - httpcore.http11 - DEBUG - response_closed.started
2025-09-21 08:56:28,967 - httpcore.http11 - DEBUG - response_closed.complete
2025-09-21 08:56:28,968 - telegram.ext.ExtBot - DEBUG - Call to Bot API endpoint `getMe` finished with return value `{'id': 546065661, 'is_bot': True, 'first_name': 'freqtrad_test', 'username': 'xmatt_freq_test_bot', 'can_join_groups': True, 'can_read_all_group_messages': False, 'supports_inline_queries': False, 'can_connect_to_business': False, 'has_main_web_app': False}`
2025-09-21 08:56:28,968 - telegram.ext.ExtBot - DEBUG - This Bot is already initialized.
2025-09-21 08:56:29,969 - telegram.ext.Application - DEBUG - This Application is already initialized.
2025-09-21 08:56:30,971 - telegram.ext.Application - DEBUG - This Application is already initialized.
2025-09-21 08:56:31,972 - telegram.ext.Application - DEBUG - This Application is already initialized.

# Pressed ctrl+c here - it would continue like this forever!

2025-09-21 08:56:32,355 - telegram.ext.Application - DEBUG - Application received stop signal. Shutting down.
2025-09-21 08:56:32,356 - httpcore.connection - DEBUG - close.started
2025-09-21 08:56:32,356 - httpcore.connection - DEBUG - close.complete
2025-09-21 08:56:32,356 - telegram.ext.ExtBot - DEBUG - This Bot is already shut down. Returning.
2025-09-21 08:56:32,356 - telegram.ext.Updater - DEBUG - Shut down of Updater complete

Additional Context

This is most likely caused by failing to break out of the below loop if boostrap_retries is set to -1 (which sets infinite_loop to True).

Because of this - the bot fails to exit network_retry loop() even if the actual action failed.
I think expected behavior here is to have the bot to retry indefinitely if the action fails - but not retry indefinitely independent of the outcome of the action.

while effective_is_running():
try:
await do_action()
if not infinite_loop:
_LOGGER.debug("%s Action succeeded. Stopping loop.", log_prefix)
break
except RetryAfter as exc:


bootstrap_retries (:obj:`int`, optional): Whether the bootstrapping phase
(calling :meth:`initialize` and the boostrapping of
:meth:`telegram.ext.Updater.start_polling`)
will retry on failures on the Telegram server.
* < 0 - retry indefinitely
* 0 - no retries (default)
* > 0 - retry up to X times
.. versionchanged:: 21.11
The default value will be changed to from ``-1`` to ``0``. Indefinite retries
during bootstrapping are not recommended.

The docstring explicitly mentions this as supported ("< 0 - retry indefinitely") - but as not recommended.

I can understand this is not recommended - but it should either be marked as not supported entirely (fail on startup?) - or should not result in an endless loop.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions