{"record":{"id":"7e17f7ebd84c0ce2","repo":"Billionmail/BillionMail","slug":"mailbox-s-already-exists","errorCode":null,"errorMessage":"mailbox %s already exists","messagePattern":"mailbox (.+?) already exists","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/internal/service/mail_boxes/mail_boxes.go","lineNumber":49,"sourceCode":"\tif err != nil {\n\t\terr = fmt.Errorf(\"Generate password md5-crypt failed: %w\", err)\n\t\treturn\n\t}\n\n\tmailbox.Username = strings.ToLower(mailbox.Username)\n\tmailbox.LocalPart = strings.ToLower(mailbox.LocalPart)\n\tmailbox.Domain = strings.ToLower(mailbox.Domain)\n\n\tnow := time.Now().Unix()\n\tmailbox.CreateTime = now\n\tmailbox.UpdateTime = now\n\tmailbox.Active = 1\n\tmailbox.Maildir = fmt.Sprintf(\"%s@%s/\", mailbox.LocalPart, mailbox.Domain)\n\n\t_, err = g.DB().Model(\"mailbox\").Ctx(ctx).Insert(mailbox)\n\tif err != nil {\n\t\tif strings.Contains(err.Error(), \"duplicate\") || strings.Contains(err.Error(), \"unique\") {\n\t\t\treturn fmt.Errorf(\"mailbox %s already exists\", mailbox.Username)\n\t\t}\n\t\treturn err\n\t}\n\t// maildirsize\n\tif e2 := ensureMaildirAndQuotaFile(ctx, mailbox); e2 != nil {\n\t\tg.Log().Warning(ctx, \"ensureMaildirAndQuotaFile failed\", e2)\n\t}\n\treturn nil\n}\n\nfunc Update(ctx context.Context, mailbox *v1.Mailbox) (err error) {\n\tmailbox.UpdateTime = time.Now().Unix()\n\tif mailbox.Password != \"\" {\n\t\tmailbox.PasswordEncode = PasswdEncode(ctx, mailbox.Password)\n\t\tmailbox.Password, err = PasswdMD5Crypt(ctx, mailbox.Password)\n\n\t\tif err != nil {\n\t\t\terr = fmt.Errorf(\"Generate password md5-crypt failed: %w\", err)","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/mail_boxes/mail_boxes.go#L31-L67","documentation":"Add inserts the new mailbox row into the 'mailbox' table; if the DB rejects the insert with a duplicate/unique constraint violation, it is translated into this friendly 'mailbox %s already exists' error instead of surfacing the raw SQL error.","triggerScenarios":"Inserting a mailbox whose username already exists in the mailbox table (unique constraint); two concurrent Add calls racing to create the same address; re-running mailbox creation for an existing user; soft-deleted rows still occupying the unique key.","commonSituations":"User double-submits the create-mailbox form; import scripts re-run without idempotency; case-sensitivity mismatch — usernames are lowercased before insert but callers checked existence with mixed case; leftover row after an alias/domain rename.","solutions":["Check mailbox existence (SELECT by lowercased username) before calling Add","Catch this error and surface a friendly 'address already in use' message to the end user","Handle concurrent creation with upsert (INSERT ... ON CONFLICT DO NOTHING) or a unique-check inside a transaction","Purge soft-deleted/duplicate rows that still hold the unique key"],"exampleFix":"// before\n_, err = g.DB().Model(\"mailbox\").Ctx(ctx).Insert(mailbox)\nif err != nil {\n\tif strings.Contains(err.Error(), \"duplicate\") || strings.Contains(err.Error(), \"unique\") {\n\t\treturn fmt.Errorf(\"mailbox %s already exists\", mailbox.Username)\n\t}\n\treturn err\n}\n// after\ncount, err := g.DB().Model(\"mailbox\").Ctx(ctx).Where(\"username = ?\", mailbox.Username).Count()\nif err != nil {\n\treturn err\n}\nif count > 0 {\n\treturn fmt.Errorf(\"mailbox %s already exists\", mailbox.Username)\n}\n_, err = g.DB().Model(\"mailbox\").Ctx(ctx).Insert(mailbox)","handlingStrategy":"try-catch","validationCode":"count, err := g.DB().Model(\"mailbox\").Ctx(ctx).\n\tWhere(\"username = ?\", strings.ToLower(username)).Count()\nif err != nil {\n\treturn err\n}\nif count > 0 {\n\treturn fmt.Errorf(\"mailbox %s already exists\", username)\n}","typeGuard":null,"tryCatchPattern":"err := mail_boxes.Add(ctx, mailbox)\nif err != nil && strings.Contains(err.Error(), \"already exists\") {\n\t// friendly UX: surface 'address already in use' to the user\n\treturn consts.NewDuplicateMailboxError(mailbox.Username)\n}\nif err != nil {\n\treturn err\n}","preventionTips":["Always lowercase usernames before existence checks and inserts","Use upsert / ON CONFLICT for idempotent creation flows","Make import scripts idempotent (skip existing usernames)","Purge soft-deleted rows that still hold the unique key"],"tags":["database","duplicate-key","mailbox","unique-constraint"],"backgroundTag":"duplicate-key-constraint","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}