- id: go-cor-001 title: "Goroutine launched without synchronisation" severity: medium languages: [go] tags: [correctness, concurrency] pattern: 'go\s+func\s*\(' exclude_pattern: 'wg\.|\.Go\(|context\.|done\s*<-|select\s*\{' fix: "Use a WaitGroup, errgroup, or context cancellation to track goroutine lifecycle" found_in: [go-process] example_bad: 'go func() { doWork() }()' example_good: 'wg.Add(1); go func() { defer wg.Done(); doWork() }()' first_seen: "2026-03-09" detection: regex auto_fixable: false - id: go-cor-002 title: "WaitGroup.Wait without timeout or context" severity: low languages: [go] tags: [correctness, concurrency] pattern: '\.Wait\(\)' exclude_pattern: 'select\s*\{|ctx\.Done|context\.With|time\.After' fix: "Wrap Wait() in a select with context.Done() or time.After() to prevent indefinite blocking" found_in: [go-process] example_bad: 'wg.Wait()' example_good: | done := make(chan struct{}) go func() { wg.Wait(); close(done) }() select { case <-done: case <-ctx.Done(): } first_seen: "2026-03-09" detection: regex auto_fixable: false - id: go-cor-003 title: "Silent error swallowing with blank identifier" severity: medium languages: [go] tags: [correctness, errors] pattern: '^\s*_\s*=\s*\w+\.\w+\(' exclude_pattern: 'defer|Close\(|Flush\(' fix: "Handle the error explicitly — log it, return it, or document why it is safe to discard" found_in: [go-store, go-cache] example_bad: '_ = service.Process(data)' example_good: | if err := service.Process(data); err != nil { return fmt.Errorf("processing: %w", err) } first_seen: "2026-03-09" detection: regex auto_fixable: false - id: go-cor-004 title: "Panic in library code" severity: high languages: [go] tags: [correctness, panic] pattern: '\bpanic\(' exclude_pattern: '_test\.go|// unreachable|Must\w+\(' fix: "Return an error instead of panicking — panics in libraries crash the caller" found_in: [go-io, go-config] example_bad: 'panic("unexpected state")' example_good: 'return fmt.Errorf("unexpected state: %v", state)' first_seen: "2026-03-09" detection: regex auto_fixable: false - id: go-cor-005 title: "File deletion without path validation" severity: high languages: [go] tags: [correctness, filesystem] pattern: 'os\.Remove(All)?\(' exclude_pattern: 'filepath\.Clean|ValidatePath|strings\.Contains.*\.\.' fix: "Validate the path before deletion to prevent removing unintended files or directories" found_in: [go-io] example_bad: 'os.RemoveAll(userProvidedPath)' example_good: | cleanPath := filepath.Clean(userProvidedPath) if !strings.HasPrefix(cleanPath, safeBase) { return fmt.Errorf("path outside safe directory") } os.RemoveAll(cleanPath) first_seen: "2026-03-09" detection: regex auto_fixable: false - id: go-cor-006 title: "HTTP response error discarded" severity: high languages: [go] tags: [correctness, errors, http] pattern: 'resp,\s*_\s*:=.*\.(Get|Post|Do|Send)\(' fix: "Always check the error from HTTP calls — network failures are common" found_in: [go-api] example_bad: 'resp, _ := http.Get(url)' example_good: | resp, err := http.Get(url) if err != nil { return fmt.Errorf("fetching %s: %w", url, err) } defer resp.Body.Close() first_seen: "2026-03-09" detection: regex auto_fixable: false - id: go-cor-007 title: "Wrong signal type (syscall.Signal instead of os.Signal)" severity: low languages: [go] tags: [correctness, portability] pattern: 'syscall\.Signal\b' exclude_pattern: 'os\.Signal' fix: "Use os.Signal for portable signal handling across platforms" found_in: [go-process] example_bad: 'ch := make(chan syscall.Signal, 1)' example_good: 'ch := make(chan os.Signal, 1)' first_seen: "2026-03-09" detection: regex auto_fixable: true