{"record":{"id":"f3f030a6c36b4fd2","repo":"affaan-m/ECC","slug":"unauthorized-f3f030","errorCode":null,"errorMessage":"unauthorized","messagePattern":"unauthorized","errorType":"error_code","errorClass":"ErrUnauthorized","httpStatus":null,"severity":"warning","filePath":"skills/golang-patterns/SKILL.md","lineNumber":131,"sourceCode":"```\n\n### Custom Error Types\n\n```go\n// Define domain-specific errors\ntype ValidationError struct {\n    Field   string\n    Message string\n}\n\nfunc (e *ValidationError) Error() string {\n    return fmt.Sprintf(\"validation failed on %s: %s\", e.Field, e.Message)\n}\n\n// Sentinel errors for common cases\nvar (\n    ErrNotFound     = errors.New(\"resource not found\")\n    ErrUnauthorized = errors.New(\"unauthorized\")\n    ErrInvalidInput = errors.New(\"invalid input\")\n)\n```\n\n### Error Checking with errors.Is and errors.As\n\n```go\nfunc HandleError(err error) {\n    // Check for specific error\n    if errors.Is(err, sql.ErrNoRows) {\n        log.Println(\"No records found\")\n        return\n    }\n\n    // Check for error type\n    var validationErr *ValidationError\n    if errors.As(err, &validationErr) {\n        log.Printf(\"Validation error on field %s: %s\",","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/skills/golang-patterns/SKILL.md#L113-L149","documentation":"A Go sentinel error ErrUnauthorized = errors.New(\"unauthorized\") from the golang-patterns skill, listed alongside ErrNotFound and ErrInvalidInput as one of the common-case domain sentinels. It is matched with errors.Is and wrapped with context where the failure occurs.","triggerScenarios":"An auth middleware or service returns/wraps ErrUnauthorized when credentials are missing, invalid, or insufficient. Subsequent layers wrap it with fmt.Errorf(\"...: %w\", ErrUnauthorized) to add context without losing the sentinel identity.","commonSituations":"JWT signature verification fails; token expired; missing Authorization header; user role below the required level; API key revoked.","solutions":["Verify the Authorization header exists and is well-formed before invoking the service.","Refresh short-lived tokens before they expire to avoid the unauthorized path entirely.","At the handler, map errors.Is(err, ErrUnauthorized) to 401 for missing/invalid creds and use a separate sentinel for 403 forbidden.","Log the specific cause server-side but return a generic message to avoid information leakage."],"exampleFix":"// before\nvar ErrUnauthorized = errors.New(\"unauthorized\")\n\n// after: separate authentication from authorization\nvar (\n    ErrUnauthenticated = errors.New(\"unauthenticated\")\n    ErrForbidden       = errors.New(\"forbidden\")\n)","handlingStrategy":"validation","validationCode":"// verify credentials before reaching the protected service\nif !auth.HasValidToken(r) {\n    http.Error(w, \"unauthorized\", http.StatusUnauthorized)\n    return\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Authenticate in middleware before the service runs.","Split ErrUnauthenticated (401) from ErrForbidden (403).","Refresh tokens before expiry."],"tags":["go","sentinel-error","authentication","authorization"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}