# fatal error: sync: unlock of unlocked mutex

- **ID:** `go/mutex-unlock-of-unlocked-mutex`
- **Domain:** go
- **Category:** runtime_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## Root Cause

Unlock() is called on a sync.Mutex that is not currently locked, usually from a deferred Unlock on an error path where Lock was never reached.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| 1.18 | active | — | — |
| 1.20 | active | — | — |
| 1.22 | active | — | — |

## Workarounds

1. **** (95% success)
   ```
   mu.Lock()
defer mu.Unlock()
// critical section
   ```
2. **** (88% success)
   ```
   func lock(mu *sync.Mutex) func() {
    mu.Lock()
    return mu.Unlock
}
unlock := lock(&mu)
defer unlock()
   ```

## Dead Ends

- **** — The mutex state is inconsistent; subsequent Lock calls may deadlock or panic unpredictably. (75% fail)
- **** — RWMutex has the same Unlock semantics, so the bug persists. (70% fail)
