Skip to content
Latchkey

Go "DATA RACE" in goroutine - Fix in CI

The race detector flags concurrent unsynchronized access where at least one operation is a write. It reports the two goroutines and stacks so you can add the missing synchronization.

What this error means

go test -race fails with WARNING: DATA RACE and two stacks reading/writing the same address. Shared state is mutated from multiple goroutines without a lock.

go
==================
WARNING: DATA RACE
Write at 0x00c0000a4010 by goroutine 8:
  example.com/app.(*Counter).Inc()
      counter.go:14 +0x...
Previous read at 0x00c0000a4010 by goroutine 7:
  example.com/app.(*Counter).Value()
      counter.go:18 +0x...
==================

Common causes

Unsynchronized shared state

Multiple goroutines read and write the same variable without a mutex or channel.

Closure capturing a loop variable

Goroutines share a captured variable that the loop mutates, racing on it.

How to fix it

Guard shared state with a mutex

  1. Protect every access to the shared field with the same lock.
Go
mu.Lock()
c.n++
mu.Unlock()

Use atomics for counters

  1. Replace a plain counter with an atomic type so increments are race-free.
Go
var n atomic.Int64
n.Add(1)

How to prevent it

  • Run go test -race in CI on concurrent code.
  • Guard all shared state with a mutex or use atomics.
  • Pass loop variables explicitly into goroutines.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →