# WARNING: DATA RACE: Write by goroutine X, Read by goroutine Y (channel send/recv)

- **ID:** `go/goroutine-racy-channel-send-recv`
- **Domain:** go
- **Category:** runtime_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## Root Cause

Sending a pointer to a struct via channel, then modifying the struct in sender while receiver reads it.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| 1.0 | active | — | — |
| 1.20 | active | — | — |

## Workarounds

1. **Send value instead of pointer** (95% success)
   ```
   ch := make(chan MyStruct)
go func() {
    s := MyStruct{Field: 42}
    ch <- s // copy of s
}()
s := <-ch
   ```
2. **Use mutex to protect shared struct** (85% success)
   ```
   type Shared struct {
    mu sync.Mutex
    data MyStruct
}
var s Shared
ch := make(chan *Shared)
go func() {
    s.mu.Lock()
    s.data.Field = 42
    s.mu.Unlock()
    ch <- &s
}()
   ```

## Dead Ends

- **Assuming channel synchronization protects the data** — Channel synchronizes the send/recv operation, not the data pointed to. (90% fail)
- **Copying pointer before send** — Copying pointer doesn't deep copy the struct; still shared. (80% fail)
