MHSanaei/3x-ui · warning

bot not started

Error message

bot not started

What it means

testTgBot delegates the actual send through testTgFunc, a function variable registered at startup by the web layer to avoid a circular import with the tgbot package. If the variable is still nil the handler returns 'bot not started' — meaning the Telegram bot runtime was never wired up in this process (typically the bot is disabled or failed to start, so nothing called SetTestTgFunc).

Source

Thrown at internal/web/controller/setting.go:312

}

func (a *SettingController) testTgBot(c *gin.Context) {
	enabled, err := a.settingService.GetTgbotEnabled()
	if err != nil || !enabled {
		jsonMsg(c, I18nWeb(c, "pages.settings.tgBotNotEnabled"), errors.New("telegram bot disabled"))
		return
	}
	// Import tgbot package would create a circular dependency, so we call
	// the test through the global function registered at startup.
	if testTgFunc != nil {
		if err := testTgFunc(); err != nil {
			jsonMsg(c, I18nWeb(c, "pages.settings.tgTestFailed")+": "+err.Error(), err)
			return
		}
		jsonMsg(c, I18nWeb(c, "pages.settings.tgTestSuccess"), nil)
		return
	}
	jsonMsg(c, I18nWeb(c, "pages.settings.tgBotNotRunning"), errors.New("bot not started"))
}

// testTgFunc is set from web layer to test Telegram sending without circular imports.
var testTgFunc func() error

// SetTestTgFunc registers the function used to test Telegram sending.
func SetTestTgFunc(fn func() error) { testTgFunc = fn }

// reloadTgbotFunc is wired from the web layer; importing tgbot here would be a circular dependency.
var reloadTgbotFunc func()

func SetReloadTgbotFunc(fn func()) { reloadTgbotFunc = fn }

// emailService is set from web layer.
var emailService *email.EmailService

// SetEmailService registers the email service for test endpoints.
func SetEmailService(s *email.EmailService) { emailService = s }

View on GitHub (pinned to ad32144c42)

Solutions

  1. Restart the panel so the web layer registers the bot and SetTestTgFunc runs
  2. Verify the tgbot package actually initialized (look for its startup log lines)
  3. If custom wiring was removed, restore the SetTestTgFunc call in the web bootstrap
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Bot enabled in settings but startup wiring never ran (init error swallowed); calling the endpoint in a process/CLI mode that skips web-server boot; a race where the test fires before startup registration.

Common situations: Immediately after enabling the bot but before a restart; custom builds that strip the tgbot registration; startup partial failure.

Related errors


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