MHSanaei/3x-ui · warning
username can not be empty
Error message
username can not be empty
What it means
UpdateFirstUser in internal/web/service/panel/user.go updates the first (admin) user record; it rejects an empty username string before touching the database. The username doubles as the admin login name, so an empty value would lock everyone out of the panel.
Solutions
- Send a non-empty username in the request payload that reaches UpdateFirstUser
- On the caller side, default or validate the field before calling the service (fail fast at the API boundary)
- If driven by a script, quote and check the variable: [ -n "$USERNAME" ] before invoking
Example fix
// before
err := userService.UpdateFirstUser("", "newpass")
// after
if username == "" {
return fmt.Errorf("username required")
}
err := userService.UpdateFirstUser(username, "newpass") Defensive patterns
Strategy: validation
Validate before calling
if strings.TrimSpace(username) == "" {
return errors.New("username required")
}
err := userService.UpdateFirstUser(username, password) Prevention
- Validate non-empty username at the API boundary before calling the service
- Reject the whole request early instead of relying on the service guard
- Treat empty-string form fields as missing, not as valid values
When it happens
Trigger: Calling service.UpdateFirstUser("", password) — e.g. a settings-update API request where the username field was omitted from the JSON payload and defaulted to "", or a CLI/script invoking the setter with an unset variable.
Common situations: Frontend form submitted without the username field; automation script passing an empty shell variable (unquoted $USER_VAR); API client built from a struct where Username was never set.
Related errors
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/a6ae0116ebcf7a75.
Report an issue: GitHub.
Appendix: source
Thrown at internal/web/service/panel/user.go:145
if twoFactorEnable {
_ = s.settingService.SetTwoFactorEnable(false)
_ = s.settingService.SetTwoFactorToken("")
}
return db.Model(model.User{}).
Where("id = ?", id).
Updates(map[string]any{
"username": username,
"password": hashedPassword,
"login_epoch": gorm.Expr("login_epoch + 1"),
}).
Error
}
func (s *UserService) UpdateFirstUser(username string, password string) error {
if username == "" {
return errors.New("username can not be empty")
} else if password == "" {
return errors.New("password can not be empty")
}
hashedPassword, er := crypto.HashPasswordAsBcrypt(password)
if er != nil {
return er
}
db := database.GetDB()
user := &model.User{}
err := db.Model(model.User{}).First(user).Error
if database.IsNotFound(err) {
user.Username = username
user.Password = hashedPassword
return db.Model(model.User{}).Create(user).Error
} else if err != nil {
return errView on GitHub (pinned to ad32144c42)