This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: go-chi-context-deadline-goroutine-drain-standard

Go Chi HTTP Context Propagation and Goroutine Drain Standard

Mandates strict propagation of `r.Context()` across all downstream operations, RPC boundaries, and internal concurrency fan-outs in Go Chi services. Eliminates silent goroutine leaks, connection starvation, and zombie downstream execution by enforcing deterministic select-based cancellation and bounded lifecycle decoupling.

Prohibited Anti-Pattern: Spawning unanchored fire-and-forget goroutines or discarding r.Context() via context.Background() during request handling

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Go Chi HTTP Context Propagation and Goroutine Drain Standard - Mandates strict propagation of `r.Context()` across all downstream operations, RPC boundaries, and internal concurrency fan-outs in Go Chi services. Eliminates silent goroutine leaks, connection starvation, and zombie downstream execution by enforcing deterministic select-based cancellation and bounded lifecycle decoupling.
globs: **/*.go, cmd/**/*.go, internal/**/*.go, pkg/**/*.go
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/go-chi-context-deadline-goroutine-drain-standard"
---

# Go Chi HTTP Context Propagation and Goroutine Drain Standard

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Spawning unanchored fire-and-forget goroutines or discarding r.Context() via context.Background() during request handling

## System Constraints
You are a Principal Software Architect enforcing the Go Chi Context Deadline & Goroutine Drain Standard. You must rigorously reject any code where `r.Context()` is severed from downstream I/O calls, where child goroutines are spawned without select-branches on `ctx.Done()`, or where asynchronous background tasks outliving the request capture a raw `r.Context()` without bounded decoupling (e.g., `context.WithoutCancel`). Enforce absolute leak-free concurrency and predictable teardown under client disconnects.

## Strict Guidelines
- Engineers MUST ALWAYS pass `r.Context()` to all downstream database transactions, cache lookups, and outbound RPC/HTTP clients invoked synchronously within the request lifecycle.
- Engineers MUST NOT spawn detached fire-and-forget goroutines (`go func() { ... }()`) using `r.Context()`, as client disconnects immediately cancel the context and truncate critical mutations midway.
- Engineers MUST NOT overwrite or discard `r.Context()` with `context.Background()` or `context.TODO()` within request pipelines simply to bypass client deadline timeouts.
- When asynchronous operations MUST survive client disconnects (e.g., audit logging, async metrics), engineers MUST detach via `context.WithoutCancel(r.Context())` (Go 1.21+) combined with an explicit bounded timeout (`context.WithTimeout`), or enqueue the task into an application-scoped worker pool.
- All channel operations, fan-out loops, and worker pipelines within the request lifecycle MUST select against `ctx.Done()` on every send and receive to prevent permanent goroutine deadlocks on canceled requests.
- HTTP middleware chains in Chi MUST include `middleware.Timeout` and `middleware.Recoverer` to establish deterministic upper bounds and guard against unhandled panics crashing listener loops.

## Bad vs Good Implementations
### Asynchronous Task Dispatch & Fan-Out Pipeline in Go Chi

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: 1. Discards client context and timeout by initializing a disconnected `context.Background()` for the downstream RPC call. 2. Fires an unanchored goroutine that references `r.Context()`, causing immediate failure if the HTTP client disconnects before completion. 3. The channel send (`ch <- err`) is unbuffered and unmonitored; if the parent handler exits early, the background goroutine blocks indefinitely, causing a critical goroutine memory leak.
```go
package handlers

import (
	"context"
	"net/http"
	"time"
)

func ProcessTransactionHandler(w http.ResponseWriter, r *http.Request) {
	// BAD: Stripping context deadline with Background()
	ctx := context.Background()
	
	// BAD: Goroutine leak; if client disconnects, unbuffered channel write hangs forever
	ch := make(chan error)
	go func() {
		// BAD: Uses r.Context() inside fire-and-forget task; gets canceled on client disconnect
		err := auditLogger.Log(r.Context(), "transaction_initiated")
		ch <- err
	}()

	resp, err := paymentClient.Charge(ctx, 100)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
	w.Write(resp)
}
```

#### Production Standard (Correct)
> **Standard**: 1. Propagates `r.Context()` to `paymentClient.Charge`, instantly canceling downstream I/O if the client aborts. 2. Uses `context.WithoutCancel(ctx)` paired with a strict 5-second `WithTimeout` for the non-blocking background audit log, ensuring safe completion without leaking resources or inheriting client aborts. 3. Gracefully inspects `ctx.Err()` to prevent unnecessary error responses on client disconnection.
```go
package handlers

import (
	"context"
	"errors"
	"net/http"
	"time"
)

func ProcessTransactionHandler(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	// GOOD: Decouple detached task safely using WithoutCancel and an explicit bounded deadline
	go func() {
		asyncCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 5*time.Second)
		defer cancel()
		
		if err := auditLogger.Log(asyncCtx, "transaction_initiated"); err != nil {
			logger.ErrorContext(asyncCtx, "async audit log failed", "err", err)
		}
	}()

	// GOOD: Downstream RPC preserves client deadlines and cancellation
	resp, err := paymentClient.Charge(ctx, 100)
	if err != nil {
		if errors.Is(ctx.Err(), context.Canceled) {
			// Client disconnected early; drop downstream response cleanly
			return
		}
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
	w.Write(resp)
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Go Chi HTTP Context Propagation and Goroutine Drain Standard

Go Chi HTTP Context Propagation and Goroutine Drain Standard defines an industrial-grade behavioral standard for backend engineering. Mandates strict propagation of `r.Context()` across all downstream operations, RPC boundaries, and internal concurrency fan-outs in Go Chi services. Eliminates silent goroutine leaks, connection starvation, and zombie downstream execution by enforcing deterministic select-based cancellation and bounded lifecycle decoupling. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Spawning unanchored fire-and-forget goroutines or discarding r.Context() via context.Background() during request handling Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftSpawning unanchored fire-and-forget goroutines or discarding r.Context() via context.Background() during request handlingCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS pass `r.Context()` to all downstream database transactions, cache lookups, and outbound RPC/HTTP clients invoked synchronously within the request lifecycle.

Engineers MUST ALWAYS pass `r.Context()` to all downstream database transactions, cache lookups, and outbound RPC/HTTP clients invoked synchronously within the request lifecycle.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT spawn detached fire-and-forget goroutines (`go func() { ... }()`) using `r.Context()`, as client disconnects immediately cancel the context and truncate critical mutations midway.

Engineers MUST NOT spawn detached fire-and-forget goroutines (`go func() { ... }()`) using `r.Context()`, as client disconnects immediately cancel the context and truncate critical mutations midway.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST NOT overwrite or discard `r.Context()` with `context.Background()` or `context.TODO()` within request pipelines simply to bypass client deadline timeouts.

Engineers MUST NOT overwrite or discard `r.Context()` with `context.Background()` or `context.TODO()` within request pipelines simply to bypass client deadline timeouts.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

When asynchronous operations MUST survive client disconnects (e.g., audit logging, async metrics), engineers MUST detach via `context.WithoutCancel(r.Context())` (Go 1.21+) combined with an explicit bounded timeout (`context.WithTimeout`), or enqueue the task into an application-scoped worker pool.

When asynchronous operations MUST survive client disconnects (e.g., audit logging, async metrics), engineers MUST detach via `context.WithoutCancel(r.Context())` (Go 1.21+) combined with an explicit bounded timeout (`context.WithTimeout`), or enqueue the task into an application-scoped worker pool.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

All channel operations, fan-out loops, and worker pipelines within the request lifecycle MUST select against `ctx.Done()` on every send and receive to prevent permanent goroutine deadlocks on canceled requests.

All channel operations, fan-out loops, and worker pipelines within the request lifecycle MUST select against `ctx.Done()` on every send and receive to prevent permanent goroutine deadlocks on canceled requests.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

HTTP middleware chains in Chi MUST include `middleware.Timeout` and `middleware.Recoverer` to establish deterministic upper bounds and guard against unhandled panics crashing listener loops.

HTTP middleware chains in Chi MUST include `middleware.Timeout` and `middleware.Recoverer` to establish deterministic upper bounds and guard against unhandled panics crashing listener loops.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Go Chi HTTP Context Propagation and Goroutine Drain Standard critical for AI coding assistants?

Mandates strict propagation of `r.Context()` across all downstream operations, RPC boundaries, and internal concurrency fan-outs in Go Chi services. Eliminates silent goroutine leaks, connection starvation, and zombie downstream execution by enforcing deterministic select-based cancellation and bounded lifecycle decoupling. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Spawning unanchored fire-and-forget goroutines or discarding r.Context() via context.Background() during request handling) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

Go