agentsclimarketplace

Go context

Skill muratmirgun/gophers/skills/go-context

26 production-grade Go skills for Claude Code, Gemini CLI, and opencode.

Install
npx -y skills add muratmirgun/gophers --skill go-context

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 8 stars8 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

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.

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

6.3 KB, as published. Nobody here has run it

Go Context Usage

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.

Core Rules

  1. ctx is the first parameter, named ctx context.Context. No exceptions outside interface stubs imposed by external APIs.
  2. Propagate the caller's ctx all the way down. Do not start a new tree with context.Background() inside a request path.
  3. Do not store Context in a struct. Pass it to each method that needs it.
  4. Always defer cancel() after WithCancel/WithTimeout/WithDeadline, unless ownership is explicitly transferred.
  5. Context values are for request-scoped metadata only (request ID, auth principal, trace). Never for optional function parameters or config.
  6. Value keys must be unexported named types to prevent cross-package collisions.

Where Does Data Belong?

Pick the most explicit option that fits — context values are the last resort.

OptionUse forWhy
Function parameterAnything the function needs to do its jobType-checked, visible at call site
Method receiverState that belongs to the typeAlready in scope
Package-level configProcess-wide, immutableOne owner, no hidden flow
context.ValueRequest-scoped metadata that crosses layers without being a function argUntyped — use sparingly

Read references/values-and-keys.md for the unexported-key pattern, typed accessors, and OpenTelemetry/trace propagation.

Constructors

SituationUse
main, init, top-level testcontext.Background()
Placeholder while plumbing is incompletecontext.TODO()
Inside an HTTP handlerr.Context()
Need manual cancellationcontext.WithCancel(parent)
Need a deadline / timeoutcontext.WithTimeout(parent, d) / WithDeadline
Background work that must outlive the request (Go 1.21+)context.WithoutCancel(parent)

Propagation: The One Rule

// 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)
}

Deriving and Cancelling

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.

Don't Wrap 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) { /* ... */ }

Enforce With Linters

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-Patterns

Anti-patternWhy it hurtsDo this instead
ctx context.Context stored on a struct fieldLifetime becomes invisible; outlives the requestPass ctx to each method
context.Background() mid-callCancellation chain breaks; goroutines leakUse the caller's ctx
ctx.Value("user-id") with a string keyCross-package collisions, no type safetyUnexported key type + typed getter
Passing nil as a contextPanics on Done() / Value()Use context.TODO() while plumbing
WithTimeout without defer cancel()Leaks the timer until parent finishesdefer cancel() on the next line
Custom MyContext interfaceBreaks every standard signatureKeep context.Context, extract with helpers

Verification Checklist

  • Every function that does I/O, blocks, or calls another ctx-aware API takes ctx context.Context as its first parameter.
  • No context.Context field on any struct (search: ctx\s+context\.Context inside type ... struct).
  • Every WithCancel/WithTimeout/WithDeadline is followed by defer cancel() on the next line.
  • No context.Background() or context.TODO() calls inside request handlers.
  • All context value keys are unexported named types, accessed via typed getters.
  • golangci-lint run --enable=contextcheck,noctx passes.

References

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.