{"record":{"id":"576e8380e4834149","repo":"MHSanaei/3x-ui","slug":"the-new-username-and-password-are-empty","errorCode":null,"errorMessage":"The new username and password are empty","messagePattern":"The new username and password are empty","errorType":"validation","errorClass":null,"httpStatus":200,"severity":"warning","filePath":"internal/web/controller/setting.go","lineNumber":184,"sourceCode":"\t}\n\tjsonMsg(c, I18nWeb(c, \"pages.settings.toasts.modifySettings\"), err)\n}\n\n// updateUser updates the current user's username and password.\nfunc (a *SettingController) updateUser(c *gin.Context) {\n\tform := &updateUserForm{}\n\terr := c.ShouldBind(form)\n\tif err != nil {\n\t\tjsonMsg(c, I18nWeb(c, \"pages.settings.toasts.modifySettings\"), err)\n\t\treturn\n\t}\n\tuser := session.GetLoginUser(c)\n\tif user.Username != form.OldUsername || !crypto.CheckPasswordHash(user.Password, form.OldPassword) {\n\t\tjsonMsg(c, I18nWeb(c, \"pages.settings.toasts.modifyUserError\"), errors.New(I18nWeb(c, \"pages.settings.toasts.originalUserPassIncorrect\")))\n\t\treturn\n\t}\n\tif form.NewUsername == \"\" || form.NewPassword == \"\" {\n\t\tjsonMsg(c, I18nWeb(c, \"pages.settings.toasts.modifyUserError\"), errors.New(I18nWeb(c, \"pages.settings.toasts.userPassMustBeNotEmpty\")))\n\t\treturn\n\t}\n\tif err := a.settingService.VerifyTwoFactorCode(form.TwoFactorCode); err != nil {\n\t\tjsonMsg(c, I18nWeb(c, \"pages.settings.toasts.modifyUserError\"), err)\n\t\treturn\n\t}\n\terr = a.userService.UpdateUser(user.Id, form.NewUsername, form.NewPassword)\n\tif err == nil {\n\t\tuser.Username = form.NewUsername\n\t\tuser.Password, _ = crypto.HashPasswordAsBcrypt(form.NewPassword)\n\t\tif saveErr := session.SetLoginUser(c, user); saveErr != nil {\n\t\t\terr = saveErr\n\t\t}\n\t}\n\tjsonMsg(c, I18nWeb(c, \"pages.settings.toasts.modifyUser\"), err)\n}\n\n// restartPanel restarts the panel service after a delay.","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/web/controller/setting.go#L166-L202","documentation":"updateUser requires BOTH newUsername and newPassword to be non-empty after the old-credential check passes; leaving either blank returns this i18n message (pages.settings.toasts.userPassMustBeNotEmpty). The API does not support changing only one of the two fields through this endpoint — even if you only want a new password, you must resend the current username as the new username.","triggerScenarios":"POSTing the update form with newUsername filled but newPassword empty (or vice versa); a frontend client that omits empty fields via JSON omitting instead of sending them.","commonSituations":"UI forms that treat the password box as optional; API scripts that only update one credential; whitespace-only values after trim.","solutions":["Send both fields: to keep the username, set newUsername to the existing username","If you need one-field-only updates, extend updateUserForm handling server-side rather than sending blanks","Validate non-empty in the client before submitting"],"exampleFix":"// before\n{ oldUsername, oldPassword, newPassword: 'newpass' }\n\n// after\n{ oldUsername, oldPassword, newUsername: 'admin', newPassword: 'newpass' }","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(form.NewUsername) == \"\" || strings.TrimSpace(form.NewPassword) == \"\" {\n    return errors.New(\"both new username and new password are required\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Require both new fields in the client form before enabling submit","To keep one unchanged, resend its current value rather than blanks","Mark both inputs as required in the UI"],"tags":["validation","settings","api","authentication"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}