When the caller gives up and walks away, the work behind the request should stop too. This is the Go plumbing that carries that cancellation, and a deadline, down through every layer.
WHEN TO USE
SCOPE
USE FOR
Propagate the same context from an HTTP handler through the service and database layers.
Choose correctly between context.Background, context.TODO, and context.WithoutCancel.
Add a timeout or deadline to a downstream call with WithTimeout or WithDeadline.
Store a request-scoped value like a request ID safely using an unexported key type.
Keep a background cleanup task running after its parent HTTP request has already returned.
NOT FOR
Not for code that simply accepts ctx as a first parameter with no propagation question.
This is a saved copy of the skill's SKILL.md instructions. It may differ from the upstream file or the version you install.
Community default. A company skill that explicitly supersedes samber/cc-skills-golang@golang-context skill takes precedence.
Go context.Context Best Practices
context.Context is Go's mechanism for propagating cancellation signals, deadlines, and request-scoped values across API boundaries and between goroutines. Think of it as the "session" of a request — it ties together every operation that belongs to the same unit of work.
Best Practices Summary
Propagate the same context through the entire request lifecycle: HTTP handler → service → DB → external APIs — any link that starts a fresh context keeps working after the client is gone.
Take ctx as the first parameter, named ctx context.Context — the fixed position is what makes context-aware APIs recognizable at a glance and what linters check.
Pass context through function parameters instead of storing it in a struct — the struct outlives the request that filled it, so later calls reuse a context that is already cancelled or belongs to someone else.
Pass context.TODO() rather than a nil context — nil panics on the first Done() or Value() call, far from the caller that passed it.
Call cancel() on all control-flow paths for WithCancel/WithTimeout/WithDeadline, unless ownership of the context and cancel function is explicitly returned or transferred — an uncalled cancel() keeps the child attached to its parent and leaks its timer until the parent finishes.
Create context.Background() only at top-level entry points (main, init, tests). Deeper in the call chain — especially mid-request — it detaches the work from the caller's deadline and cancellation, the propagation break shown below.
Use context.TODO() as a placeholder when a context is needed but none exists yet — it marks the gap for a later fix instead of hiding it behind a Background() that looks deliberate.
Declare context value keys as unexported types — with a plain string key, two packages using "user" silently overwrite each other.
Carry only request-scoped metadata in context values, never function parameters — values retrieved through Value() lose compile-time typing and disappear from the function signature.
Use context.WithoutCancel (Go 1.21+) when spawning background work that must outlive the parent request — otherwise the handler returning cancels the audit log or cleanup just started.
Creating Contexts
Situation
Use
Entry point (main, init, test)
context.Background()
Function needs context but caller doesn't provide one yet
context.TODO()
Inside an HTTP handler
r.Context()
Need cancellation control
context.WithCancel(parentCtx)
Need a deadline/timeout
context.WithTimeout(parentCtx, duration)
Context Propagation: The Core Principle
The most important rule: propagate the same context through the entire call chain. When you propagate correctly, cancelling the parent context cancels all downstream work automatically.
// ✗ Bad — creates a new context, breaking the chain
func (s *OrderService) Create(ctx context.Context, order Order) error {
return s.db.ExecContext(context.Background(), "INSERT INTO orders ...", order.ID)
}
// ✓ Good — propagates the caller's context
func (s *OrderService) Create(ctx context.Context, order Order) error {
return s.db.ExecContext(ctx, "INSERT INTO orders ...", order.ID)
}
Deep Dives
Cancellation, Timeouts & Deadlines — How cancellation propagates: WithCancel for manual cancellation, WithTimeout for automatic cancellation after a duration, WithDeadline for absolute time deadlines. Patterns for listening (<-ctx.Done()) in concurrent code, AfterFunc callbacks, and WithoutCancel for operations that must outlive their parent request (e.g., audit logs).
Context Values & Cross-Service Tracing — Safe context value patterns: unexported key types to prevent namespace collisions, when to use context values (request ID, user ID) vs function parameters. Trace context propagation: OpenTelemetry trace headers, correlation IDs for log aggregation, and marshaling/unmarshaling context across service boundaries.
Context in HTTP Servers & Service Calls — HTTP handler context: r.Context() for request-scoped cancellation, middleware integration, and propagating to services. HTTP client patterns: NewRequestWithContext, client timeouts, and retries with context awareness. Database operations: always use *Context variants (QueryContext, ExecContext) to respect deadlines.
Cross-References
→ See the samber/cc-skills-golang@golang-concurrency skill for goroutine cancellation patterns using context
→ See the samber/cc-skills-golang@golang-database skill for context-aware database operations (QueryContext, ExecContext)
→ See the samber/cc-skills-golang@golang-observability skill for trace context propagation with OpenTelemetry
→ See the samber/cc-skills-golang@golang-design-patterns skill for timeout and resilience patterns
Enforce with Linters
Many context pitfalls are caught automatically by linters: govet, staticcheck. → See the samber/cc-skills-golang@golang-lint skill for configuration and usage.
No requirements beyond installing this skill were found.
Listed as free
Connected services may require an account or charge fees.
Run this outside your AI tool, using Node.js 22.20.0 or newer. Skills CLI 1.7.2 skips skill selection; prompts cancel installation without an interactive terminal. If choosing Project when asked about installation scope, open your project's folder before running this.
Install checklist
Check selected tools if a picker appears; Claude Code may be unchecked under Additional agents. ↑/↓ moves, Space toggles selections, Enter confirms.
Without a tool picker, check Installing to: for your intended tool. Stop if it names a different tool.
If asked, choose Symlink (Recommended) for shared files or Copy to all agents for separate copies; review the summary before confirming installation.
Install the find-skills skill? defaults to Yes, adding another skill for all projects. Choose No if you don't want that extra installation.
Skills CLI 1.7.2 sends install data to skills.sh by default, including the source, skill names, target tools and file details; GitHub sources are reported only when GitHub confirms the repository is public, while other remote sources can also be reported. Confirmed-public GitHub sources also trigger a security-audit request. Before installing, set the environment variable DO_NOT_TRACK=1 or DISABLE_TELEMETRY=1 to disable both.
After installing for Claude Code, open it in the installation project if you chose Project; Global makes the skill available across projects on this computer. Once Claude Code loads the skill, its description helps Claude decide when to use it.
If installation created a top-level skills folder that did not exist when your Claude Code session started, run /reload-skills in that session. Run it again after later changes in that folder.
Install the whole plugin
This route installs the Samber Golang Skills plugin package selected for your AI tool.
Add Samuel's marketplace, then install the plugin
Type both lines inside a Claude Code session, not at your shell prompt. The marketplace is a separate repository of Samuel Berthe's, samber/cc, which also lists his other plugins. The second line opens the details of cc-skills-golang, which carries this repository's 46 Go skills; pick one of the install options shown and Claude Code installs it.
01
/plugin marketplace add samber/cc
02
/plugin install cc-skills-golang@samber
Run it in your terminal. It copies the whole repository, with its 46 skills, into ~/.openclaw/skills/cc-skills-golang, OpenClaw's skills folder in your home folder. To install it for one OpenClaw workspace instead, Samuel gives ~/.openclaw/workspace/skills/cc-skills-golang as the folder.
Run it in your terminal, not inside Gemini CLI; installing from GitHub needs git on your computer. It installs the repository, with its 46 skills, as a Gemini CLI extension. To update it later, run gemini extensions update cc-skills-golang.
Run it in your terminal. It copies the whole repository, with its 46 skills, into ~/.cursor/skills/cc-skills-golang, Cursor's skills folder in your home folder.
Type it in an interactive GitHub Copilot CLI session, not at your shell prompt. It installs the repository straight from GitHub as a plugin, with its 46 skills and no marketplace to add first.
Golang benchmarking, profiling, and performance measurement. Use when writing, running, or comparing Go benchmarks, profiling hot paths with pprof, interpreting CPU/memory/trace profiles, analyzing results with benchstat, setting up CI benchmark regression detection, or investigating production performance with Prometheus runtime metrics. Also use when the developer needs deep analysis on a specific performance indicator - this skill provides the measurement methodology, while samber/cc-skills-golang@golang-performance provides the optimization patterns.Read full description
Golang CLI application development. Use when building, modifying, or reviewing a Go CLI tool — especially for command structure, flag handling, configuration layering, version embedding, exit codes, I/O patterns, signal handling, shell completion, argument validation, and CLI unit testing. Also triggers when code uses cobra, viper, or urfave/cli. For cobra-specific APIs → See samber/cc-skills-golang@golang-spf13-cobra skill; for viper configuration layering → See samber/cc-skills-golang@golang-spf13-viper skill.Read full description
Golang code style conventions — line length and breaking, variable declarations, control flow clarity, when comments help vs hurt. Use when writing or reviewing Go code, asking about style or clarity, or establishing project coding standards. Not for naming conventions (→ See samber/cc-skills-golang@golang-naming skill), linter configuration (→ See samber/cc-skills-golang@golang-lint skill), or doc comments (→ See samber/cc-skills-golang@golang-documentation skill).Read full description
Golang concurrency patterns. Use when writing or reviewing concurrent Go code involving goroutines, channels, select, locks, sync primitives, errgroup, singleflight, worker pools, or fan-out/fan-in pipelines. Also triggers when you detect goroutine leaks, race conditions, channel ownership issues, or need to choose between channels and mutexes.Read full description
CI/CD pipeline configuration using GitHub Actions for Golang projects — testing, linting, SAST, security scanning, code coverage, Dependabot, Renovate, GoReleaser, code review automation, and release pipelines. Use when setting up or improving Go project CI, configuring GitHub Actions workflows, adding linters or security scanners, automating dependency updates, or adding quality gates.Read full description
Golang data structures — slices (internals, capacity growth, preallocation, slices package), maps (internals, hash buckets, maps package), arrays, container/list/heap/ring, strings.Builder vs bytes.Buffer, generic collections, pointers (unsafe.Pointer, weak.Pointer), and copy semantics. Use when choosing or optimizing Go data structures, implementing generic containers, using container/ packages, unsafe or weak pointers, or questioning slice/map internals. Not for applying optimization patterns once profiling has identified a bottleneck (→ See samber/cc-skills-golang@golang-performance skill).Read full description