From gophers
Use when designing, propagating, or debugging context.Context flow in Go — first-parameter placement, deadlines and cancellation, request-scoped values, WithoutCancel for fire-and-forget work, and key-collision-safe value patterns. Apply proactively whenever a function takes ctx, spawns work, or accepts request-scoped data, even if the user has not asked about context.
How this skill is triggered — by the user, by Claude, or both
Slash command
/gophers:go-contextThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
`context.Context` carries the cancellation, deadline, and request-scoped values for a single unit of work. Pass it explicitly through the entire call chain — never store it, never replace it with `Background()` mid-flight, never use it as a side-channel for ordinary parameters.
context.Context carries the cancellation, deadline, and request-scoped values for a single unit of work. Pass it explicitly through the entire call chain — never store it, never replace it with Background() mid-flight, never use it as a side-channel for ordinary parameters.
ctx is the first parameter, named ctx context.Context. No exceptions outside interface stubs imposed by external APIs.ctx all the way down. Do not start a new tree with context.Background() inside a request path.Context in a struct. Pass it to each method that needs it.defer cancel() after WithCancel/WithTimeout/WithDeadline, unless ownership is explicitly transferred.Pick the most explicit option that fits — context values are the last resort.
| Option | Use for | Why |
|---|---|---|
| Function parameter | Anything the function needs to do its job | Type-checked, visible at call site |
| Method receiver | State that belongs to the type | Already in scope |
| Package-level config | Process-wide, immutable | One owner, no hidden flow |
context.Value | Request-scoped metadata that crosses layers without being a function arg | Untyped — use sparingly |
Read references/values-and-keys.md for the unexported-key pattern, typed accessors, and OpenTelemetry/trace propagation.
| Situation | Use |
|---|---|
main, init, top-level test | context.Background() |
| Placeholder while plumbing is incomplete | context.TODO() |
| Inside an HTTP handler | r.Context() |
| Need manual cancellation | context.WithCancel(parent) |
| Need a deadline / timeout | context.WithTimeout(parent, d) / WithDeadline |
| Background work that must outlive the request (Go 1.21+) | context.WithoutCancel(parent) |
// Bad — breaks the chain, downstream cannot be cancelled
func (s *OrderService) Create(ctx context.Context, o Order) error {
return s.db.ExecContext(context.Background(), insertSQL, o.ID)
}
// Good — same ctx flows HTTP handler -> service -> DB -> external API
func (s *OrderService) Create(ctx context.Context, o Order) error {
return s.db.ExecContext(ctx, insertSQL, o.ID)
}
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel() // release resources even on the happy path
select {
case <-ctx.Done():
return ctx.Err()
case res := <-doAsync(ctx):
return res
}
Read references/cancellation-and-deadlines.md for
WithoutCancel,AfterFunc, and long-running goroutine cancellation patterns.
Context in Custom Types// Bad — pollutes the standard signature
type MyCtx interface {
context.Context
UserID() string
}
// Good — keep the signature standard, extract via helper
func UserIDFrom(ctx context.Context) (string, bool) { /* ... */ }
Most context mistakes are mechanical and a linter will catch them in CI before review:
govet -vet=context — flags non-first context.Context parameters and lost cancels.staticcheck SA1012 — calls passing nil context.contextcheck (golangci-lint) — verifies downstream calls propagate ctx.noctx — flags HTTP/SQL APIs called without their *Context variant.Run golangci-lint run --enable=contextcheck,noctx,staticcheck in CI for any project that exposes context.Context.
| Anti-pattern | Why it hurts | Do this instead |
|---|---|---|
ctx context.Context stored on a struct field | Lifetime becomes invisible; outlives the request | Pass ctx to each method |
context.Background() mid-call | Cancellation chain breaks; goroutines leak | Use the caller's ctx |
ctx.Value("user-id") with a string key | Cross-package collisions, no type safety | Unexported key type + typed getter |
Passing nil as a context | Panics on Done() / Value() | Use context.TODO() while plumbing |
WithTimeout without defer cancel() | Leaks the timer until parent finishes | defer cancel() on the next line |
Custom MyContext interface | Breaks every standard signature | Keep context.Context, extract with helpers |
ctx-aware API takes ctx context.Context as its first parameter.context.Context field on any struct (search: ctx\s+context\.Context inside type ... struct).WithCancel/WithTimeout/WithDeadline is followed by defer cancel() on the next line.context.Background() or context.TODO() calls inside request handlers.golangci-lint run --enable=contextcheck,noctx passes.WithoutCancel, AfterFunc, goroutine cancellationNewRequestWithContext, QueryContext/ExecContextProvides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub muratmirgun/gophers --plugin gophers