cloudflare / cloudflare/cloudflare-go
Race Condition Issue : Protect union registry with sync.Map to prevent concurrent write panics (race condition)
- Dominant language
- Go
- Stars
- 2.1k
- Forks
- 781
- Avg merge
- 12h 38m
- Merged PRs (30d)
- 4
Description
Confirm this is a Go library issue and not an underlying Cloudflare API issue
- [x] This is an issue with the Go library
## Describe the Bug
### Problem
The union registry (`unionRegistry` and `unionVariants` global maps in `internal/apijson/registry.go`) are unprotected and not thread-safe.
When multiple goroutines call `RegisterUnion()` simultaneously, the Go runtime panics with:
```text
fatal error: concurrent map writes
```
The issue occurs because both global maps are written concurrently without synchronization.
---
## Vulnerable Code
**File:** `internal/apijson/registry.go`
```go
// Lines 15-16: Unprotected maps
var unionRegistry = map[reflect.Type]unionEntry{}
var unionVariants = map[reflect.Type]interface{}{}
// Lines 24-30: Concurrent writes cause panic
func RegisterUnion(typ reflect.Type, discriminator string, variants ...UnionVariant) {
unionRegistry[typ] = unionEntry{...} // concurrent write
for _, variant := range variants {
unionVariants[variant.Type] = typ // concurrent write
}
}
```
Multiple goroutines calling `RegisterUnion()` simultaneously can trigger a runtime panic.
---
## Steps To Reproduce
1. Create multiple goroutines that call `RegisterUnion()` concurrently.
2. Run the race demo test repeatedly.
3. The runtime eventually panics with `concurrent map writes`.
---
## Command
```bash
go test ./internal/apijson -run TestBareMapConcurrency -v -count=50
```
---
## Expected Behavior
The registry should support concurrent registration safely without panicking.
Expected approaches could include:
- protecting the maps with `sync.RWMutex`
- using `sync.Map`
- or ensuring registration only happens during initialization
---
## Actual Output
```text
=== RUN TestBareMapConcurrency
fatal error: concurrent map writes
goroutine 12 [running]:
runtime/maps.go:1046 +0x18
github.com/cloudflare/cloudflare-go/v7/internal/apijson.TestBareMapConcurrency.func1(0x5)
internal/apijson/registry_race_demo_test.go:138 +0x128
Process exit code: 2
```
---
## Error
```text
fatal error: concurrent map writes
```
---
## Environment
### OS
Windows/amd64
### Go Version
Go 1.22.0
### Library Version
`github.com/cloudflare/cloudflare-go/v7`
Contributor guide
Assessment
This issue has not been assessed yet.