Member-only story
Why Context Keys Must Be Typed in Go
A few days ago, a colleague approached me with a puzzling issue. She was writing unit tests for a function that relied on values stored in the Go context, and although everything looked right, the tests kept failing. The context values weren’t being retrieved correctly — even though the same keys and values were used in both the actual code and the test.
Turns out, she had stumbled upon a subtle but important detail about how context.WithValue works in Go.
Let’s walk through what happened — and why the type of the context key matters just as much as its value.
🤔 The Problem
Here’s a simplified version of the original code:
// constants.go
type contextKey string
const ReqIDKey contextKey = "request-id"
// handler.go
func A() {
ctx := context.WithValue(context.Background(), ReqIDKey, "req-123")
resp, err := B(ctx)
// ...
}
// service.go
func B(ctx context.Context) {
reqID := ctx.Value(ReqIDKey)
fmt.Println(reqID) // "req-123"
}Now in the test, this was written:
// handler_test.go
func TestB(t *testing.T) {
ctx := context.WithValue(context.Background(), "request-id", "req-123")
B(ctx) // reqID is nil!
}