
Golang Samber Oops
Teach your coding agent to use samber/oops correctly—low-cardinality messages, fluent .With() context, domains via .In(), and nil-safe Wrap—in Go services.
Overview
golang-samber-oops is an agent skill for the Build phase that implements samber/oops error patterns in Go backends with APM-safe low-cardinality messages and structured attributes.
Install
npx skills add https://github.com/samber/cc-skills-golang --skill golang-samber-oopsWhat is this skill?
- Enforces low-cardinality static Errorf/Wrapf messages with variable IDs in .With() for APM grouping
- Uses fluent builder chaining (.In(), .With(), Wrap) instead of fmt.Errorf or errors.New
- Documents oops.Wrap nil passthrough so callers need not guard before wrap
- Eval-driven scenarios for order-processing and multi-layer service errors
- Aligns errors with domain/feature context via .In() for clearer incident triage
- Eval cases explicitly test low-cardinality messages vs .With() attributes
- Covers nil passthrough behavior for oops.Wrap without pre-checks
Adoption & trust: 3.4k installs on skills.sh; 2k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your Go agent sprinkles dynamic IDs into error strings or uses fmt.Errorf, so production errors fragment in APM and lose consistent domain context.
Who is it for?
Indie Go developers building microservices or monolith APIs who already chose samber/oops and want agents to follow library-specific observability rules.
Skip if: Projects not using Go or teams standardized on plain errors.Join without oops who do not plan to adopt the library.
When should I use this skill?
Writing or reviewing Go service error handling that should use samber/oops instead of fmt.Errorf.
What do I get? / Deliverables
Your service code uses oops fluent builders with static messages, .With() metadata, .In() domains, and nil-safe wraps ready for structured logging and tracing.
- Go functions using oops builders with static messages and .With() context
- Boundary wraps that preserve error chains without nil guards
Recommended Skills
Journey fit
Error-handling structure is implemented while building backend Go code, before ship-time observability reviews catch grouping failures. Backend is the canonical shelf for service-layer error propagation, APM-friendly attributes, and wrap patterns in Go APIs and workers.
How it compares
Library-specific Go error-style skill, not a generic Go lint pass or HTTP framework tutorial.
Common Questions / FAQ
Who is golang-samber-oops for?
Solo builders writing Go backend services who use samber/oops and need agents to match its cardinality and wrapping conventions.
When should I use golang-samber-oops?
Use it in Build (backend) while adding handlers, repos, or jobs that return errors; revisit in Ship (review) when auditing observability before release.
Is golang-samber-oops safe to install?
It guides code patterns only; review Security Audits on this page and treat generated error attributes like any other potentially sensitive log field.
SKILL.md
READMESKILL.md - Golang Samber Oops
[ { "id": 1, "name": "low-cardinality-error-messages", "description": "Tests the critical rule: variable data goes in .With() attributes, not interpolated into the message string", "prompt": "I'm using samber/oops in my Go service. Write error handling for a function that processes orders. When an order fails, I need to include the user ID, tenant ID, and order ID in the error for debugging.", "trap": "Model may interpolate all variables into the Errorf message string (e.g., Errorf('failed to process order %s for user %s in tenant %s', orderID, userID, tenantID)) which breaks APM grouping", "assertions": [ {"id": "1.1", "text": "Uses .With() for user_id, tenant_id, and order_id instead of interpolating them into the message"}, {"id": "1.2", "text": "The Errorf/Wrapf message string is static/low-cardinality (no variable interpolation for IDs)"}, {"id": "1.3", "text": "Uses the fluent builder pattern (chained method calls)"}, {"id": "1.4", "text": "Does NOT use fmt.Errorf or errors.New for the error creation"}, {"id": "1.5", "text": "Includes .In() to set the domain/feature context"} ] }, { "id": 2, "name": "wrap-nil-passthrough", "description": "Tests that oops.Wrap returns nil if err is nil, so no nil check is needed", "prompt": "I have a Go function using samber/oops. It calls another function that may return nil or an error. How should I handle the return value? Here's my code:\n\n```go\nfunc ProcessData(ctx context.Context) error {\n err := fetchData(ctx)\n if err != nil {\n return oops.In(\"processor\").Wrapf(err, \"fetch failed\")\n }\n return nil\n}\n```\n\nIs there a simpler way to write this?", "trap": "Model may say the code is fine as-is, not knowing that oops.Wrap/Wrapf returns nil when err is nil, making the nil check unnecessary", "assertions": [ {"id": "2.1", "text": "Identifies that the nil check is unnecessary because oops.Wrapf returns nil if err is nil"}, {"id": "2.2", "text": "Shows the simplified form: return oops.In('processor').Wrapf(err, 'fetch failed') without the if block"}, {"id": "2.3", "text": "The simplified version removes both the if statement and the separate return nil"} ] }, { "id": 3, "name": "layered-error-context", "description": "Tests that each architectural layer should add context via Wrap/Wrapf at package boundaries", "prompt": "I have a 3-layer Go architecture: HTTP handler -> service -> repository. Each layer calls the next. How should I handle errors with samber/oops so that when an error reaches the top, I can see the full context of what happened at each layer?", "trap": "Model may only wrap at the top level or only at the bottom level, instead of wrapping at each layer boundary with layer-specific context", "assertions": [ {"id": "3.1", "text": "Each layer (handler, service, repository) adds its own .In() domain context"}, {"id": "3.2", "text": "Each layer wraps the error from the layer below using Wrap or Wrapf"}, {"id": "3.3", "text": "Different layers add different context attributes relevant to their scope (e.g., repository adds query/table info, handler adds request info)"}, {"id": "3.4", "text": "Uses .Tags() for categorization at one or more layers"}, {"id": "3.5", "text": "Handler layer uses .Request() to attach HTTP request context"} ] }, { "id": 4, "name": "public-vs-technical-messages", "description": "Tests the separation between user-safe public messages and technical error details", "prompt": "I'm building a Go API. When a user tries to buy a product that's out of stock, I need to return a user-friendly message to the frontend AND log detailed technical information. How do I handle this with samber/oops?", "trap": "Model may put the user-facing message in Errorf (which is for technical details) instead of using .Public() for the user-safe message", "a