Skip to content

go.global_mutable_state

Correctness High

Detects global mutable state that can cause race conditions in concurrent code.

Global mutable state causes:

  • Race conditions — Concurrent access without synchronization
  • Testing difficulties — Tests affect each other
  • Hidden dependencies — Functions have implicit state
  • Unpredictable behavior — State changes unexpectedly
// ❌ Before (unsafe global state)
var cache = make(map[string]interface{})
func Get(key string) interface{} {
return cache[key] // Race condition!
}
func Set(key string, value interface{}) {
cache[key] = value // Race condition!
}
// ✅ After (thread-safe)
var cache sync.Map
func Get(key string) (interface{}, bool) {
return cache.Load(key)
}
func Set(key string, value interface{}) {
cache.Store(key, value)
}
  • Package-level var with mutable types (maps, slices)
  • Global variables accessed from multiple goroutines
  • Missing mutex protection on shared state

Unfault generates thread-safe alternatives:

// Option 1: sync.Map for concurrent maps
var cache sync.Map
// Option 2: Mutex-protected struct
type SafeCache struct {
mu sync.RWMutex
data map[string]interface{}
}
func (c *SafeCache) Get(key string) interface{} {
c.mu.RLock()
defer c.mu.RUnlock()
return c.data[key]
}