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(), &params); 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

  1. Verify the Telegram bot is enabled in panel settings and botToken + chatId are set, then Save (this triggers a bot reload).
  2. 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.
  3. Check panel logs for a prior Start() failure — usually a 401 from Telegram meaning the token is wrong.
  4. 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

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


AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15). Data as JSON: /api/errors/3ea843ef0e55fda6. Report an issue: GitHub.