Skip to content

go.context_background

Stability Medium

Detects inappropriate use of context.Background() where a proper context should be passed.

Context carries cancellation, deadlines, and request-scoped values:

  • Lost cancellation — Parent cancellation doesn’t propagate
  • Leaked resources — Operations continue after request ended
  • No deadline propagation — Request deadline ignored
  • Missing tracing — Request tracing lost

Using context.Background() breaks the context chain that enables Go’s graceful shutdown and timeout patterns.

// ❌ Before
func (s *Service) GetUser(ctx context.Context, id string) (*User, error) {
// ctx ignored, context.Background() used instead
return s.db.QueryContext(context.Background(), "SELECT...", id)
}

If the caller’s context is cancelled, the database query continues running.

// ✅ After
func (s *Service) GetUser(ctx context.Context, id string) (*User, error) {
return s.db.QueryContext(ctx, "SELECT...", id)
}

Now cancellation and deadlines propagate correctly.

  • context.Background() when a context parameter is available
  • context.TODO() in production code (meant for development)
  • HTTP handlers not passing request context
  • gRPC handlers ignoring the context parameter

Unfault replaces context.Background() with the available context parameter.

// Main function initialization
func main() {
ctx := context.Background()
server.Start(ctx)
}
// Long-running background jobs
func StartBackgroundWorker() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
runWorker(ctx)
}
// Tests
func TestSomething(t *testing.T) {
ctx := context.Background()
// ...
}
// HTTP handlers: use request context
func (h *Handler) GetUser(w http.ResponseWriter, r *http.Request) {
user, err := h.service.GetUser(r.Context(), userID)
}
// gRPC handlers: context is first parameter
func (s *server) GetUser(ctx context.Context, req *pb.Request) (*pb.Response, error) {
return s.service.GetUser(ctx, req.Id)
}
// Chain context through all calls
func (s *Service) GetUser(ctx context.Context, id string) (*User, error) {
user, err := s.cache.Get(ctx, id)
if err != nil {
user, err = s.db.Query(ctx, id)
}
return user, err
}