{"record":{"id":"91552e656233fca5","repo":"XTLS/Xray-core","slug":"email-must-not-be-empty","errorCode":null,"errorMessage":"Email must not be empty.","messagePattern":"Email must not be empty\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/shadowsocks/validator.go","lineNumber":50,"sourceCode":"\taccount := u.Account.(*MemoryAccount)\n\tif !account.Cipher.IsAEAD() && len(v.users) > 0 {\n\t\treturn errors.New(\"The cipher is not support Single-port Multi-user\")\n\t}\n\tv.users = append(v.users, u)\n\n\tif !v.behaviorFused {\n\t\thashkdf := hmac.New(sha256.New, []byte(\"SSBSKDF\"))\n\t\thashkdf.Write(account.Key)\n\t\tv.behaviorSeed = crc64.Update(v.behaviorSeed, crc64.MakeTable(crc64.ECMA), hashkdf.Sum(nil))\n\t}\n\n\treturn nil\n}\n\n// Del a Shadowsocks user with a non-empty Email.\nfunc (v *Validator) Del(email string) error {\n\tif email == \"\" {\n\t\treturn errors.New(\"Email must not be empty.\")\n\t}\n\n\tv.Lock()\n\tdefer v.Unlock()\n\n\temail = strings.ToLower(email)\n\tidx := -1\n\tfor i, u := range v.users {\n\t\tif strings.EqualFold(u.Email, email) {\n\t\t\tidx = i\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif idx == -1 {\n\t\treturn errors.New(\"User \", email, \" not found.\")\n\t}\n\tulen := len(v.users)","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/shadowsocks/validator.go#L32-L68","documentation":"Guard error in Validator.Del: deleting a user requires a non-empty email because email is the lookup key. An empty string would otherwise be ambiguous (multiple unnamed users). Pure input-validation failure with no state change.","triggerScenarios":"Calling Validator.Del(\"\") — typically from an API handler or panel that omitted the email field when issuing the remove-user request.","commonSituations":"Management panel form submitted without selecting a user; API client sending {email: \"\"} or omitting email; scripts iterating a user list where one entry lacks an email.","solutions":["Supply the exact email of an existing user to Del.","Fix the panel/script to validate non-empty email before calling the API.","If the target user genuinely has no email, assign one first (edit user), then delete."],"exampleFix":"// before\nvalidator.Del(\"\")\n// after\nvalidator.Del(\"alice@example.com\")","handlingStrategy":"validation","validationCode":"func delUser(v *Validator, email string) error {\n  if strings.TrimSpace(email) == \"\" {\n    return errors.New(\"email required to delete a user\")\n  }\n  return v.Del(strings.TrimSpace(email))\n}","typeGuard":"func isValidEmail(s string) bool { return strings.TrimSpace(s) != \"\" }","tryCatchPattern":null,"preventionTips":["Require a selected user in panel delete forms.","Trim and check emails in API middleware before reaching the validator."],"tags":["shadowsocks","validation","users","api","input-validation"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}