MHSanaei/3x-ui · error
bot not initialized
Error message
bot not initialized
What it means
Returned by Tgbot.TestConnection when the package-level bot handle is nil. The Telegram bot in this panel is a lazily-initialized global (guarded by tgBotMutex); if Start() was never called or failed (bad token, disabled in settings), the handle stays nil and every test call short-circuits here before any network traffic happens.
Source
Thrown at internal/web/service/tgbot/tgbot_send.go:267
}
params := telego.DeleteMessageParams{
ChatID: tu.ID(chatId),
MessageID: messageID,
}
if err := bot.DeleteMessage(context.Background(), ¶ms); err != nil {
logger.Warning("Failed to delete message:", err)
} else {
logger.Info("Message deleted successfully")
}
}
// TestConnection verifies the bot token is valid and the API is reachable.
func (t *Tgbot) TestConnection() error {
tgBotMutex.Lock()
b := bot
tgBotMutex.Unlock()
if b == nil {
return fmt.Errorf("bot not initialized")
}
me, err := b.GetMe(context.Background())
if err != nil {
return fmt.Errorf("API unreachable: %w", err)
}
_ = me
return nil
}
View on GitHub (pinned to ad32144c42)
Solutions
- Verify the Telegram bot is enabled in panel settings and botToken + chatId are set, then Save (this triggers a bot reload).
- Call Start() (or the reload endpoint wired via SetReloadTgbotFunc) before testing, or simply use the panel's test endpoint which checks IsRunning() first and gives the clearer 'telegram bot is not running' message.
- Check panel logs for a prior Start() failure — usually a 401 from Telegram meaning the token is wrong.
- Treat this state as permanent until reconfiguration: do not retry, reconfigure.
Example fix
// before
if err := s.tgbotService.TestConnection(); err != nil { ... }
// after — gate on running state first so the user gets an actionable message
if !s.tgbotService.IsRunning() {
return fmt.Errorf("telegram bot is not running (check token and chat ID)")
}
if err := s.tgbotService.TestConnection(); err != nil { ... } Defensive patterns
Strategy: validation
Validate before calling
// Before testing, check the bot is actually running
if !tgbotSvc.IsRunning() {
// reconfigure (token/chatId/enable) instead of calling TestConnection
return errors.New("configure and start the telegram bot first")
} Type guard
null
Try / catch
if err := tgbotSvc.TestConnection(); err != nil {
if strings.Contains(err.Error(), "bot not initialized") {
// permanent state: reload bot config, do not retry
}
} Prevention
- Always gate test calls behind IsRunning().
- Save Telegram settings (which reloads the bot) before testing.
When it happens
Trigger: Calling the Telegram test endpoint (SetTestTgFunc wiring in web.go checks IsRunning() first, but direct TestConnection calls bypass that) while the bot setting is disabled, the token is empty/invalid so Start() failed, or after Stop() has run.
Common situations: Admin clicks 'test Telegram' before filling in botToken/chatId, or toggles the bot off then hits a stale test button; also during panel startup before the tgbot job has started the bot.
Related errors
- bot not started
- telegram bot disabled
- ❌ Failed to get inbounds.
- telegram bot is not running (check token and chat ID)
- database is not initialized
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/3ea843ef0e55fda6.
Report an issue: GitHub.