Skip to content
Latchkey

Go t.Parallel() Shared-State Races - Fix Flaky Parallel Tests in CI

Calling t.Parallel() lets tests run concurrently. When several parallel tests touch the same global variable, shared file, or process-wide setting, they race - producing intermittent failures or a data-race report that only shows up under -race and load.

What this error means

Parallel tests pass alone but fail intermittently together, with a DATA RACE on a shared variable, a clobbered shared temp file, or a t.Setenv panic. The flakiness is timing-dependent and worse under -race or higher -parallel.

go test output
==================
WARNING: DATA RACE
Write at 0x... by goroutine 9:
  app/cache_test.go:21 +0x...
# or:
panic: testing: t.Setenv called after t.Parallel; cannot set environment in parallel test

Common causes

Parallel tests sharing mutable global state

Two t.Parallel() tests read/write the same package-level variable or singleton, so their concurrent access races.

t.Setenv combined with t.Parallel

t.Setenv mutates process-wide environment and is forbidden in parallel tests; Go panics when both are used in the same test.

A shared file or temp path across parallel tests

Parallel tests writing the same fixed temp file or directory clobber each other non-deterministically.

How to fix it

Give each parallel test isolated state

Use per-test locals and t.TempDir() so concurrent tests do not share mutable resources.

Go
func TestA(t *testing.T) {
	t.Parallel()
	dir := t.TempDir()   // unique per test
	// operate on local state, not package globals
}

Do not mix t.Setenv with t.Parallel

Keep env-mutating tests serial, or inject configuration instead of using process env.

Go
func TestEnv(t *testing.T) {
	// no t.Parallel() here
	t.Setenv("API_URL", "http://localhost")
}

Run with the race detector to surface the conflict

Terminal
go test -race -count=1 ./...

How to prevent it

  • Keep parallel tests free of shared mutable globals.
  • Use t.TempDir() and per-test locals for isolation.
  • Never combine t.Setenv with t.Parallel(); run env tests serially.

Frequently asked questions

What causes "t.Parallel() shared-state race"?
Two t.Parallel() tests read/write the same package-level variable or singleton, so their concurrent access races.
How do I fix t.Parallel() shared-state race?
Use per-test locals and t.TempDir() so concurrent tests do not share mutable resources.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card