RepoPilotOpen in app →

pkg/errors

Simple error handling primitives

Healthy

Healthy across all four use cases

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 6w ago
  • 37+ active contributors
  • BSD-2-Clause licensed
Show all 6 evidence items →
  • CI configured
  • Concentrated ownership — top contributor handles 54% of recent commits
  • No test directory detected

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/pkg/errors)](https://repopilot.app/r/pkg/errors)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/pkg/errors on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: pkg/errors

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/pkg/errors shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • Last commit 6w ago
  • 37+ active contributors
  • BSD-2-Clause licensed
  • CI configured
  • ⚠ Concentrated ownership — top contributor handles 54% of recent commits
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live pkg/errors repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/pkg/errors.

What it runs against: a local clone of pkg/errors — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in pkg/errors | Confirms the artifact applies here, not a fork | | 2 | License is still BSD-2-Clause | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | Last commit ≤ 71 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>pkg/errors</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of pkg/errors. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/pkg/errors.git
#   cd errors
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of pkg/errors and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "pkg/errors(\\.git)?\\b" \\
  && ok "origin remote is pkg/errors" \\
  || miss "origin remote is not pkg/errors (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(BSD-2-Clause)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"BSD-2-Clause\"" package.json 2>/dev/null) \\
  && ok "license is BSD-2-Clause" \\
  || miss "license drift — was BSD-2-Clause at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 71 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~41d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/pkg/errors"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

pkg/errors is a Go library that provides lightweight primitives for wrapping errors with contextual information while preserving the original error for inspection. It implements the Wrap() function to add context at each call level and Cause() to unwrap back to the root error, solving Go's traditional problem of error reports without debugging context or stack traces. Single-package library structured as a flat Go module: core error handling in errors.go with stack trace capture via stack.go, extensive test files (errors_test.go, format_test.go, stack_test.go, json_test.go, example_test.go), Go version-specific files (go113.go for 1.13+ compatibility), and benchmark tests (bench_test.go). No subdirectories or internal packages.

👥Who it's for

Go developers building backend services, CLIs, and libraries who need to propagate errors up the call stack with actionable context without losing the original error for debugging. Particularly valuable for teams that need consistent error handling patterns across multiple packages.

🌱Maturity & risk

Production-ready but in maintenance mode. The package has comprehensive test coverage (errors_test.go, format_test.go, json_test.go, stack_test.go), CI via Travis-CI and AppVeyor, and a stable API. However, the maintainers explicitly state the package is not accepting new functionality proposals due to Go 1.13+ native error wrapping with %w format verb and Go 2 error proposals making this approach redundant.

Low risk for existing deployments but deprecated for new projects. Go 1.13+ (released Sept 2019) natively supports error wrapping via errors.Is(), errors.As(), and %w format verbs, making this package unnecessary for modern Go code. The codebase has zero external dependencies but will not receive feature updates; rely on it only if stuck on Go <1.13 or maintaining legacy code.

Active areas of work

The repository is in maintenance mode with no active feature development. The roadmap targets a 1.0 final release after addressing outstanding PRs and removing pre-Go 1.9/1.10 support; this appears to have stalled as Go 2 error proposals superseded the package's rationale. CI pipelines (ci.yml) continue running, suggesting the repo is monitored but not actively developed.

🚀Get running

git clone https://github.com/pkg/errors.git && cd errors && go test ./... to run the test suite. No build step required; this is a library meant to be imported via import "github.com/pkg/errors".

Daily commands: This is a library, not an application. Run tests with make test (see Makefile) or go test ./... -v. Run benchmarks with go test -bench=. -benchmem bench_test.go. No server or service to start.

🗺️Map of the codebase

  • errors.go: Contains the core Wrap() and Cause() functions and the fundamental causer interface that the entire package is built around.
  • stack.go: Implements runtime.Callers() introspection to capture and format stack traces, critical for the %+v verbose error printing feature.
  • go113.go: Provides Go 1.13+ compatibility shims (errors.Is, errors.As wrapping) to coexist with standard library error handling.
  • errors_test.go: Primary test file validating Wrap/Cause behavior, error type assertions, and the causer interface contract.
  • Makefile: Defines test targets and build commands; consult this to understand the intended development workflow.

🛠️How to make changes

For bug fixes: start in errors.go (core Wrap/Cause logic) and errors_test.go (add test cases). For stack trace handling: modify stack.go and stack_test.go. For formatting behavior: edit format_test.go and the Formatter interface implementation. For Go version compatibility: update go113.go and go113_test.go. Always add tests alongside changes; use example_test.go as a template for documented examples.

🪤Traps & gotchas

None critical, but be aware: (1) This package's error wrapping is NOT the same as Go 1.13+ native wrapping—errors.Wrap() stores Cause() in a custom struct field, not via the %w verb, so errors.Is()/errors.As() from the standard library won't recognize them. (2) Stack traces are captured at Wrap() time, not error creation time, so if you create an error far from where you wrap it, you lose the original call site. (3) The go113.go file conditionally includes features only for Go 1.13+, so test on the minimum supported version.

💡Concepts to learn

  • Error wrapping / context stacking — pkg/errors solves Go's core error propagation problem—each layer can add context without destroying the original error, enabling both human-readable messages and programmatic inspection.
  • Causer interface pattern — Understanding the causer interface (Cause() error method) is central to how pkg/errors enables recursive unwrapping of error chains to find the root cause.
  • Runtime stack capture (runtime.Callers) — stack.go uses runtime.Callers() to capture the call stack at error creation time, enabling detailed %+v output for debugging without explicit error types.
  • Formatter interface / custom %v behavior — pkg/errors implements fmt.Formatter to provide %v, %+v, and %s formatting variants; understanding this pattern is essential for extending error output in Go.
  • Conditional compilation / build tags (go113.go) — The go113.go file uses version-specific implementations to bridge pkg/errors with Go 1.13+ native error handling without breaking backward compatibility.
  • Sentinel error values vs. type assertions — pkg/errors enables both patterns: unwrap with Cause() for type assertions or use errors.Is() equivalents; understanding when each applies is critical for error handling logic.
  • golang/go — The native Go error proposal and Go 1.13+ error handling (errors.Is, errors.As, %w) provides a standard library replacement for this package's functionality.
  • urfave/cli — Popular Go CLI library that historically relied on pkg/errors for context-aware error reporting in command-line applications.
  • sirupsen/logrus — Logging library for Go that integrates with pkg/errors for structured error logging with stack traces and contextual fields.
  • uber-go/zap — High-performance logging library that provides native integration with error wrapping to capture stack traces and error context.
  • cockroachdb/errors — Modern Go error library inspired by pkg/errors but extends it with better Go 1.13+ compatibility, error report aggregation, and telemetry integration.

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add Go 1.20+ native error wrapping compatibility tests in go120.go

The repo has go113.go and go113_test.go for Go 1.13 error wrapping features, but Go 1.20+ introduced errors.Join() for multiple error wrapping. Currently there's no parallel test file for Go 1.20+ features. A new go120.go and go120_test.go would test compatibility with native error.Join() semantics, ensuring pkg/errors works seamlessly alongside stdlib error handling in modern Go versions.

  • [ ] Create go120.go with build constraint +build go1.20
  • [ ] Create go120_test.go with tests for errors.Join() interoperability
  • [ ] Test that pkg/errors.Wrap() and errors.Join() can be used together without conflicts
  • [ ] Verify stack trace preservation when mixing pkg/errors with stdlib errors

Replace deprecated Travis CI and AppVeyor with GitHub Actions workflow

The repo still uses .travis.yml and appveyor.yml which are deprecated/legacy CI systems. The file .github/workflows/ci.yml exists but the README still badges Travis CI and AppVeyor. Need to migrate all CI checks to GitHub Actions, remove legacy config files, and update README badges. This modernizes the project and ensures reliable CI.

  • [ ] Expand .github/workflows/ci.yml to run tests across Go 1.18, 1.19, 1.20, 1.21+
  • [ ] Add matrix testing for linux, windows, and darwin platforms in GitHub Actions
  • [ ] Remove .travis.yml and appveyor.yml files
  • [ ] Update README.md to replace Travis CI and AppVeyor badge URLs with GitHub Actions badge

Add benchmarks for stack unwinding performance in bench_test.go

bench_test.go exists but appears to be minimal or incomplete (based on file listing). The core value proposition of pkg/errors is stack trace capture and context wrapping. Need comprehensive benchmarks comparing: (1) repeated Wrap() calls depth, (2) Format() with %+v vs %v, (3) memory overhead of stack capture vs stdlib errors. This helps contributors understand performance trade-offs.

  • [ ] Add BenchmarkWrapDepth() testing repeated Wrap() calls at various depths (10, 100, 1000)
  • [ ] Add BenchmarkFormatVerbose() comparing %+v formatting performance
  • [ ] Add BenchmarkStackCapture() measuring overhead of runtime.Callers() in WithStack()
  • [ ] Add BenchmarkCompareStdlibErrors() comparing memory/speed vs standard Go errors
  • [ ] Document benchmark results in README.md performance section

🌿Good first issues

  • Add benchmarks for the Cause() unwinding loop in bench_test.go to quantify performance regression of deeply-wrapped errors (10+ levels) vs single errors.
  • Extend format_test.go to validate %+v output format against a known golden file for all error types (wrapped, causer, plain), ensuring consistency across versions.
  • Document the exact differences between pkg/errors.Wrap() and Go 1.13+ errors.Is()/As() in README.md with side-by-side examples, since users migrating from this package to stdlib often get confused.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 87f8819 — Dummy workflow to enable GitHub Actions (tonistiigi)
  • 5dd12d0 — AddingPowerSupport_CI/Testing (#234) (santosh653)
  • 614d223 — Revert "Support Go 1.13 error chains in Cause (#215)" (#220) (aperezg)
  • 49f8f61 — Support Go 1.13 error chains in Cause (#215) (jayschwa)
  • 004deef — remove unnecessary use of fmt.Sprintf (#217) (aperezg)
  • 6d954f5 — feat: support std errors functions (#213) (Sherlock-Holo)
  • 7f95ac1 — Add support for Go 1.13 error chains (#206) (jayschwa)
  • 91f1693 — travis.yml: add Go 1.13 (aperezg)
  • ca0248e — fix travis, 1.10 doesnt support by unconvert anymore (aperezg)
  • 27936f6 — travis.yml: add Go 1.12 (#200) (davecheney)

🔒Security observations

The pkg/errors repository demonstrates strong security posture overall. It is a focused, well-maintained error handling library with minimal attack surface. No critical vulnerabilities were identified. The main areas for improvement are: (1) retiring legacy CI/CD configurations in favor of GitHub Actions, (2) establishing a formal security policy for vulnerability disclosure, and (3) ensuring explicit dependency management in go.mod. The absence of external dependencies, hardcoded secrets, injection risks, and complex infrastructure makes this a relatively low-risk package. Continued attention to dependency updates and maintaining the security policy will sustain the strong security posture.

  • Low · Outdated CI/CD Configuration Files — .travis.yml, appveyor.yml. The repository contains outdated CI/CD configuration files (.travis.yml and appveyor.yml). These legacy CI services are no longer actively maintained and have been superseded by GitHub Actions. Using outdated CI/CD systems may result in missed security updates and reduced visibility into build/test processes. Fix: Migrate completely to GitHub Actions (already present in .github/workflows/ci.yml) and remove legacy CI configuration files. Ensure the GitHub Actions workflow includes security scanning and dependency checks.
  • Low · Missing Security Policy — Repository root. No SECURITY.md or security policy file is present in the repository. This makes it difficult for security researchers to report vulnerabilities responsibly. Fix: Create a SECURITY.md file in the repository root with instructions for reporting security vulnerabilities responsibly, including a disclosure timeline and contact information.
  • Low · No Explicit Dependency Pinning in Go Module — go.mod (not provided for review). While the file structure shows Go source files typical of a Go package, there is no visibility into the go.mod file content. If dependencies are not explicitly versioned, this could lead to supply chain risks through unexpected updates. Fix: Ensure all dependencies in go.mod are explicitly pinned to specific versions. Use 'go mod verify' and 'go mod audit' to validate dependency integrity. Consider using tools like Dependabot for automated dependency security updates.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · pkg/errors — RepoPilot