cloudflare / cloudflare/cloudflare-go

Race Condition Issue : Protect union registry with sync.Map to prevent concurrent write panics (race condition)

Open
#4,326 2 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.