Skip to content

go.concurrent_map_access

Correctness Critical

Detects concurrent access to maps without proper synchronization, which causes fatal runtime panics.

Concurrent map access causes:

  • Fatal panics — Concurrent map read/write is a fatal error in Go
  • Service crashes — No recovery possible from this panic
  • Intermittent failures — Only manifests under load
  • Hard to reproduce — Depends on goroutine timing
// ❌ Before (concurrent access)
var cache = make(map[string]interface{})
func handler(w http.ResponseWriter, r *http.Request) {
key := r.URL.Query().Get("key")
cache[key] = "value" // Fatal error if concurrent!
}
// ✅ After (sync.Map)
var cache sync.Map
func handler(w http.ResponseWriter, r *http.Request) {
key := r.URL.Query().Get("key")
cache.Store(key, "value") // Thread-safe
}
  • Map writes in goroutines
  • Map access in HTTP handlers (implicitly concurrent)
  • Missing mutex protection on maps
  • Maps shared across goroutines

Unfault generates thread-safe alternatives:

// Option 1: sync.Map (best for many goroutines, infrequent writes)
var cache sync.Map
// Option 2: RWMutex (best for frequent reads, rare writes)
type SafeMap struct {
mu sync.RWMutex
data map[string]interface{}
}
func (m *SafeMap) Get(key string) interface{} {
m.mu.RLock()
defer m.mu.RUnlock()
return m.data[key]
}
func (m *SafeMap) Set(key string, val interface{}) {
m.mu.Lock()
defer m.mu.Unlock()
m.data[key] = val
}