This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: go-chi-v5-structured-middleware-graceful-shutdown

Chi v5 Context-Aware Middleware Sequencing and Graceful Server Lifecycle

Enforces strict ordering of Chi v5 middleware stacks, deterministic request context propagation, and signal-driven HTTP graceful shutdown with bounded drain intervals. Prevents goroutine leaks, unhandled context cancellations across sub-routers, and abrupt connection termination under deployment rollouts.

Prohibited Anti-Pattern: Unordered Global Middleware, Ignoring Request Contexts in Downstream Handlers, and Abrupt Process Termination via log.Fatal

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Chi v5 Context-Aware Middleware Sequencing and Graceful Server Lifecycle - Enforces strict ordering of Chi v5 middleware stacks, deterministic request context propagation, and signal-driven HTTP graceful shutdown with bounded drain intervals. Prevents goroutine leaks, unhandled context cancellations across sub-routers, and abrupt connection termination under deployment rollouts.
globs: cmd/**/*.go, internal/**/*.go, pkg/**/*.go, server/**/*.go
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/go-chi-v5-structured-middleware-graceful-shutdown"
---

# Chi v5 Context-Aware Middleware Sequencing and Graceful Server Lifecycle

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Unordered Global Middleware, Ignoring Request Contexts in Downstream Handlers, and Abrupt Process Termination via log.Fatal

## System Constraints
You are a Principal Go Architect enforcing strict Chi v5 middleware orchestration and production-ready HTTP server lifecycles. You must ensure that middleware is applied in the correct topological order (RequestID -> RealIP -> Logger -> Recoverer -> Timeout), sub-routers strictly inherit base contexts without clobbering URL params, all downstream I/O honors `r.Context()`, and server terminations employ signal.NotifyContext with bounded `http.Server.Shutdown`.

## Strict Guidelines
- Engineers MUST ALWAYS sequence global middleware starting with RequestID and RealIP, followed by structured logging, Recoverer, and bounded context timeouts.
- Engineers MUST NEVER use `http.ListenAndServe` or `log.Fatal(srv.ListenAndServe())` directly without wrapping the server in a goroutine and coordinating graceful shutdown via OS signals.
- Engineers MUST ALWAYS propagate `r.Context()` to all database queries, downstream RPC calls, and long-running operations within handlers and sub-routes.
- Engineers MUST NOT mount Chi sub-routers using `r.Handle("/prefix/*", subRouter)` when path parameters or URLParam extraction is required; use `r.Mount("/prefix", subRouter)` instead.
- Services MUST allocate a distinct, bounded context via `context.WithTimeout` (e.g., 5 to 30 seconds) for `server.Shutdown(ctx)` to allow active in-flight requests to complete during SIGTERM/SIGINT.
- Components NEVER instantiate background goroutines from within HTTP handlers using the raw request context `r.Context()`; decouple background work with a detached context or pass work to an asynchronous worker queue.

## Bad vs Good Implementations
### Chi v5 Middleware Sequencing and Signal-Driven Graceful Shutdown

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Middleware is applied in reverse/incorrect order, leading to broken panic recovery if a timeout fires. Handlers ignore r.Context(), causing queries to continue executing even if the client disconnects. Direct http.ListenAndServe terminates in-flight connections immediately upon SIGTERM.
```go
package main

import (
	"context"
	"database/sql"
	"log"
	"net/http"
	"time"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
)

func main() {
	r := chi.NewRouter()

	// ANTI-PATTERN: Timeout before Recoverer causes unrecovered panics on timeouts;
	// missing RequestID and RealIP before logger leads to untraceable requests.
	r.Use(middleware.Timeout(5 * time.Second))
	r.Use(middleware.Recoverer)
	r.Use(middleware.Logger)

	r.Get("/users/{id}", func(w http.ResponseWriter, r *http.Request) {
		// ANTI-PATTERN: Background context discards client cancellation & deadlines
		var db *sql.DB
		_ = db.QueryRowContext(context.Background(), "SELECT name FROM users WHERE id = $1", chi.URLParam(r, "id"))
		w.Write([]byte("ok"))
	})

	// ANTI-PATTERN: Abrupt termination on SIGTERM; in-flight requests get severed immediately
	log.Fatal(http.ListenAndServe(":8080", r))
}
```

#### Production Standard (Correct)
> **Standard**: Middleware follows the canonical order: RequestID and RealIP attach context metadata before Logger and Recoverer execute, with Timeout governing the downstream execution. Handlers use r.Context() to propagate client cancellation to queries. The server lifecycle executes concurrently with signal.NotifyContext and a dedicated 15-second drain window.
```go
package main

import (
	"context"
	"database/sql"
	"errors"
	"log/slog"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
)

func main() {
	logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
	r := chi.NewRouter()

	// Topologically sound middleware chain
	r.Use(middleware.RequestID)
	r.Use(middleware.RealIP)
	r.Use(middleware.Logger)
	r.Use(middleware.Recoverer)
	r.Use(middleware.Timeout(30 * time.Second))

	r.Route("/api/v1", func(api chi.Router) {
		api.Get("/users/{id}", func(w http.ResponseWriter, r *http.Request) {
			ctx := r.Context()
			userID := chi.URLParam(r, "id")

			var db *sql.DB // Injected dependency in production
			if db != nil {
				row := db.QueryRowContext(ctx, "SELECT name FROM users WHERE id = $1", userID)
				var name string
				if err := row.Scan(&name); err != nil {
					http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
					return
				}
			}
			w.WriteHeader(http.StatusOK)
			_, _ = w.Write([]byte(`{"status":"success"}`))
		})
	})

	srv := &http.Server{
		Addr:              ":8080",
		Handler:           r,
		ReadHeaderTimeout: 5 * time.Second,
		ReadTimeout:       10 * time.Second,
		WriteTimeout:      35 * time.Second,
		IdleTimeout:       60 * time.Second,
	}

	// Signal context intercepts SIGINT and SIGTERM
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()

	serverErrors := make(chan error, 1)
	go func() {
		logger.Info("server listening", slog.String("addr", srv.Addr))
		if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
			serverErrors <- err
		}
	}()

	select {
	case err := <-serverErrors:
		logger.Error("startup error", slog.String("error", err.Error()))
		os.Exit(1)
	case <-ctx.Done():
		logger.Info("shutdown signal received")
		shutdownCtx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
		defer cancel()

		if err := srv.Shutdown(shutdownCtx); err != nil {
			logger.Error("graceful shutdown failed, forcing close", slog.String("error", err.Error()))
			_ = srv.Close()
		}
		logger.Info("server shutdown cleanly")
	}
}
```

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: Chi v5 Context-Aware Middleware Sequencing and Graceful Server Lifecycle

Chi v5 Context-Aware Middleware Sequencing and Graceful Server Lifecycle defines an industrial-grade behavioral standard for backend engineering. Enforces strict ordering of Chi v5 middleware stacks, deterministic request context propagation, and signal-driven HTTP graceful shutdown with bounded drain intervals. Prevents goroutine leaks, unhandled context cancellations across sub-routers, and abrupt connection termination under deployment rollouts. 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: Unordered Global Middleware, Ignoring Request Contexts in Downstream Handlers, and Abrupt Process Termination via log.Fatal 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 DriftUnordered Global Middleware, Ignoring Request Contexts in Downstream Handlers, and Abrupt Process Termination via log.FatalCritical
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 sequence global middleware starting with RequestID and RealIP, followed by structured logging, Recoverer, and bounded context timeouts.

Engineers MUST ALWAYS sequence global middleware starting with RequestID and RealIP, followed by structured logging, Recoverer, and bounded context 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.
2

Engineers MUST NEVER use `http.ListenAndServe` or `log.Fatal(srv.ListenAndServe())` directly without wrapping the server in a goroutine and coordinating graceful shutdown via OS signals.

Engineers MUST NEVER use `http.ListenAndServe` or `log.Fatal(srv.ListenAndServe())` directly without wrapping the server in a goroutine and coordinating graceful shutdown via OS signals.

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 ALWAYS propagate `r.Context()` to all database queries, downstream RPC calls, and long-running operations within handlers and sub-routes.

Engineers MUST ALWAYS propagate `r.Context()` to all database queries, downstream RPC calls, and long-running operations within handlers and sub-routes.

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

Engineers MUST NOT mount Chi sub-routers using `r.Handle("/prefix/*", subRouter)` when path parameters or URLParam extraction is required

Engineers MUST NOT mount Chi sub-routers using `r.Handle("/prefix/*", subRouter)` when path parameters or URLParam extraction is required; use `r.Mount("/prefix", subRouter)` instead.

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

Services MUST allocate a distinct, bounded context via `context.WithTimeout` (e.g., 5 to 30 seconds) for `server.Shutdown(ctx)` to allow active in-flight requests to complete during SIGTERM/SIGINT.

Services MUST allocate a distinct, bounded context via `context.WithTimeout` (e.g., 5 to 30 seconds) for `server.Shutdown(ctx)` to allow active in-flight requests to complete during SIGTERM/SIGINT.

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

Components NEVER instantiate background goroutines from within HTTP handlers using the raw request context `r.Context()`

Components NEVER instantiate background goroutines from within HTTP handlers using the raw request context `r.Context()`; decouple background work with a detached context or pass work to an asynchronous worker queue.

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 Chi v5 Context-Aware Middleware Sequencing and Graceful Server Lifecycle critical for AI coding assistants?

Enforces strict ordering of Chi v5 middleware stacks, deterministic request context propagation, and signal-driven HTTP graceful shutdown with bounded drain intervals. Prevents goroutine leaks, unhandled context cancellations across sub-routers, and abrupt connection termination under deployment rollouts. 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 (Unordered Global Middleware, Ignoring Request Contexts in Downstream Handlers, and Abrupt Process Termination via log.Fatal) 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

Chi