{"record":{"id":"454a80e22a028d8c","repo":"affaan-m/ECC","slug":"email-cannot-be-empty","errorCode":null,"errorMessage":"email cannot be empty","messagePattern":"email cannot be empty","errorType":"validation","errorClass":"ErrEmailEmpty","httpStatus":null,"severity":"warning","filePath":"commands/go-test.md","lineNumber":131,"sourceCode":"```\n\n✓ Tests fail as expected (panic).\n\n## Step 4: Implement Minimal Code (GREEN)\n\n```go\n// validator/email.go\npackage validator\n\nimport (\n    \"errors\"\n    \"regexp\"\n)\n\nvar emailRegex = regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$`)\n\nvar (\n    ErrEmailEmpty   = errors.New(\"email cannot be empty\")\n    ErrEmailInvalid = errors.New(\"email format is invalid\")\n)\n\nfunc ValidateEmail(email string) error {\n    if email == \"\" {\n        return ErrEmailEmpty\n    }\n    if !emailRegex.MatchString(email) {\n        return ErrEmailInvalid\n    }\n    return nil\n}\n```\n\n## Step 5: Run Tests - Verify PASS\n\n```bash\n$ go test ./validator/...","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/commands/go-test.md#L113-L149","documentation":"A Go sentinel error defined as errors.New(\"email cannot be empty\") and returned by validator.ValidateEmail when the input string is the empty string. Sentinel errors are compared by identity with errors.Is. This is the first guard in the validator, checked before the regex.","triggerScenarios":"Calling ValidateEmail(\"\") or ValidateEmail with a variable that resolved to \"\" — e.g. a form field omitted, a JSON \"email\":\"\" payload, or a header that was trimmed to empty.","commonSituations":"HTTP handler binding where the client omitted the email field; leading/trailing whitespace stripped leaving empty; default zero-value string from an uninitialized struct field; CSV import with a blank email column.","solutions":["Require the email field at the API contract layer (e.g. binding:\"required,email\") so empty never reaches the validator.","Trim and check for empty before calling ValidateEmail, returning a 400 with a field-level message.","Compare with errors.Is(err, validator.ErrEmailEmpty) at the handler layer to map to the correct HTTP status and message.","If empty email is legitimately optional for this flow, skip validation rather than treating it as an error."],"exampleFix":"// before\nif email == \"\" {\n    return ErrEmailEmpty\n}\n\n// after: route by sentinel at the boundary\nif err := validator.ValidateEmail(input.Email); err != nil {\n    if errors.Is(err, validator.ErrEmailEmpty) {\n        return httpError(400, \"email\", \"email is required\")\n    }\n    if errors.Is(err, validator.ErrEmailInvalid) {\n        return httpError(400, \"email\", \"email format is invalid\")\n    }\n    return httpError(500, \"email\", \"validation failed\")\n}","handlingStrategy":"validation","validationCode":"func RequireEmail(email string) error {\n    email = strings.TrimSpace(email)\n    if email == \"\" {\n        return validator.ErrEmailEmpty\n    }\n    return validator.ValidateEmail(email)\n}","typeGuard":"func IsNonEmptyString(s string) bool { return strings.TrimSpace(s) != \"\" }","tryCatchPattern":"null","preventionTips":["Mark email as required at the binding layer (binding:\"required,email\").","Trim input before validation.","Compare with errors.Is to map to the right HTTP status."],"tags":["go","validation","email","sentinel-error"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}