go-error-review
Skill30 starsChanged 4 months agoMITView on GitHub
Review Go code for error handling correctness, nil safety, and failure-path integrity including ignored errors, missing wrapping, panic misuse, SQL/HTTP resource lifecycle, and transaction patterns. Trigger when code contains error returns, panic calls, sql.Rows, transactions, HTTP client/server code, or nil-sensitive pointer operations. Use for error-handling and correctness-focused review.
In this repository52 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- api-designSkill
- api-integration-testSkill
- constructive-thinkingSkill
- create-prSkill
- deep-researchSkill
- e2e-testSkill
- fuzzing-testSkill
- git-commitSkill
- go-benchmarkSkill
- go-ci-workflowSkill
- go-code-reviewerSkill
- go-concurrency-reviewSkill
- go-dependency-auditSkill
- go-logic-reviewSkill
- go-makefile-writerSkill
- go-observability-reviewSkill
- google-searchSkill
- go-performance-reviewSkill
- go-quality-reviewSkill
- go-review-leadSkill
- go-security-reviewSkill
- go-test-reviewSkill
- incident-postmortemSkill
- kafka-event-driven-designSkill
- load-testSkill
- local-transcriptSkill
- log-analyzerSkill
- mongo-migrationSkill
- monitoring-alertingSkill
- mysql-migrationSkill
- oceanbase-table-designSkill
- oracle-migrationSkill
- pg-migrationSkill
- readme-generatorSkill
- redis-cache-strategySkill
- security-reviewSkill
- stock-analysis-leadSkill
- stock-balance-sheet-reviewSkill
- stock-business-reviewSkill
- stock-earnings-quality-reviewSkill
- stock-industry-reviewSkill
- stock-management-reviewSkill
- stock-peer-comparison-reviewSkill
- systematic-debuggingSkill
- tdd-workflowSkill
- tech-doc-writerSkill
- thirdparty-api-integration-testSkill
- unit-testSkill
- update-docSkill
- writing-plansSkill
- yt-dlp-downloaderSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 3 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 34
Never claim tests ran unless they actually did.
- Very specific: line 37
Read go.mod. Key features:
- Distinctive: line 43
MUST quote specific code evidence.
- Distinctive: line 69
Run grep for ALL 12 checklist items against target files
- Very specific: line 190
If no issues found: state No error handling findings identified.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Go Error Review
Purpose
Audit Go code for error handling correctness, nil safety, and failure-path integrity. Core question for every function call: "What happens when it fails?"
This skill merges error handling + API request/response correctness + database operation correctness because they share one review lens: "does this code handle failure correctly?"
This skill does NOT cover: security vulnerabilities, concurrency safety, performance, code style, test quality, or business logic — those belong to sibling vertical skills.
When To Use
- Code contains error return values
- Code uses
panic/recover - Code involves
sql.Rows, transactions, connection pools - Code involves HTTP request/response body handling
- Code operates on
[]*Tpointer slices
When NOT To Use
- Security vulnerabilities →
go-security-review - Concurrency safety →
go-concurrency-review - Performance optimization →
go-performance-review - Code style →
go-quality-review - Business logic →
go-logic-review
Mandatory Gates
1) Execution Integrity Gate
Never claim tests ran unless they actually did. If not run: state reason + exact command.
2) Go Version Gate
Read go.mod. Key features:
errors.Is/errors.As(Go 1.13+)errors.Join(Go 1.20+)fmt.Errorfwith multiple%w(Go 1.20+)
3) Anti-Example Suppression Gate
MUST quote specific code evidence. Category match alone insufficient.
Embedded anti-examples:
- "Missing error handling on json.Marshal" — when marshaling known-safe struct with only primitive fields (string, int, bool, no interface fields).
json.Marshalon such structs always returns nil error. - "Missing error wrapping" — when caller already wraps; adding another layer creates redundant context like
"create user: insert user: insert row: ...". Cite the caller's wrapping code. - "Speculative nil dereference" — when caller is internal and always passes non-nil. Cite the caller code proving it never passes nil.
- "Should use errors.Is instead of ==" — direct
==against sentinel from the same package is acceptable. Cross-package comparison must useerrors.Is. - "defer f.Close() ignoring error" — acceptable for read-only file opens. Flag only for write operations where Close flushes buffered data.
4) Generated Code Exclusion Gate
Exclude: *.pb.go, *_gen.go, mock_*.go. Note excluded files in Execution Status.
Workflow
- Define scope — files/diff under review. Apply Generated Code Exclusion Gate.
- Gather evidence — read changed files, identify error-handling patterns:
if err != nil,_ =,panic(,sql.Rows,tx.,resp.Body,[]*T. - Load references — always load
go-error-and-quality.md(error sections); loadgo-api-http-checklist.mdwhen net/http code present; loadgo-database-patterns.mdwhen database code present. - Evaluate ALL 12 checklist items — for each function call, ask "what happens on failure?"
- Apply suppression → format output.
Grep-Gated Execution Protocol
This skill uses mechanical grep pre-scanning to guarantee zero missed checklist items. The model's attention is reserved for semantic judgment on grep hits and semantic-only items.
Execution Order
- Identify target files (from dispatch prompt, or write raw snippet to
$TMPDIR/review_snippet.go) - Run grep for ALL 12 checklist items against target files
- HIT → run semantic analysis to confirm or reject (true positive vs false positive)
- MISS → auto-mark NOT FOUND, skip semantic analysis for that item
- For compound patterns (item 12): run both grep patterns, apply AND logic
- Report only FOUND items (grep-confirmed + semantic-confirmed)
Grep Audit Line
Include in Execution Status: Grep pre-scan: X/12 items hit, Z confirmed as findings
Compound Pattern Protocol
Some items require two grep patterns. Run both:
- Item 12 (Log-and-return): TRIGGER when
log\.\|slog\.HIT ANDreturn.*errHIT in same file
Error Checklist (12 Items)
Error Handling (High)
| # | Item | Code Pattern Triggers | Grep Pattern |
| 1 | Ignored error | _ = or _ := on error-returning calls. Acceptable only for hash.Write, known-safe fmt.Fprintf to buffer | _\s*[:=]= |
| 2 | Missing error wrapping | return err without fmt.Errorf("context: %w", err) at abstraction boundary | return\s+(nil,\s*)?err\b |
| 3 | Panic misuse | panic() for recoverable errors. Acceptable only in init() or unrecoverable invariant violation | panic\( |
| 4 | Missing errors.Is/As | Direct == on error for cross-package sentinel; type switch instead of errors.As | err\s*[!=]=\s*|[!=]=\s*err |
| 5 | Pointer slice nil guard | []*T elements accessed without nil check before field/method access | \[\]\*\w |
API/HTTP Correctness (High)
| # | Item | Code Pattern Triggers | Grep Pattern |
| 6 | Unbounded server body | Missing http.MaxBytesReader / io.LimitReader on body decode. Do NOT require r.Body.Close() — framework handles it | r\.Body|Request\.Body|ReadAll |
| 7 | Client response body leak | resp.Body not closed on ALL paths including error path — prevents connection reuse | resp\.Body|Response\.Body |
| 8 | HTTP status code mismatch | 200 for creation (should be 201), 500 for not-found (should be 404) | WriteHeader|StatusCode|http\.Status |
Database Correctness (High)
| # | Item | Code Pattern Triggers | Grep Pattern |
| 9 | Unclosed sql.Rows | Missing defer rows.Close() AFTER error check; missing rows.Err() after iteration loop | \.Query[^R]|\.QueryRow|sql\.Rows |
| 10 | Wrong transaction rollback pattern | Missing defer tx.Rollback() + Commit override pattern | \.Begin\(|tx\. |
| 11 | sql.ErrNoRows mishandled | Treating as server error (500) instead of domain "not found" (404) | ErrNoRows |
| 12 | Log-and-return double reporting | Logging error AND returning it — causes duplicate log entries upstream | log\.|slog\. (compound: ALSO check return.*err in same file) |
Severity Rubric
High — Resource leak, crash, silent failure, data inconsistency.
Medium — Suboptimal error handling that makes debugging harder but no immediate failure.
Evidence Rules
- For each finding: explain what happens on the failure path
- For resource leaks: show the code path where Close/Rollback is missed
- For body leaks: show the error-path branch that skips Close
- Merge rule: same issue at ≥3 locations → one finding with location list
Output Format
Findings
[High|Medium] Short Title
- ID: ERR-NNN
- Location:
path:line - Impact: What happens when this code path fails
- Evidence: The missing error check / resource close / wrapping
- Recommendation: Specific fix
- Action:
must-fix|follow-up
Suppressed Items
[Suppressed] Short Title
- Reason: Anti-example matched + evidence cited
Execution Status
Go version: X.YGrep pre-scan: X/12 items hit, Z confirmed as findingsgo test: PASS | FAIL | Not run (reason + command)Excluded (generated): list or NoneReferences loaded: list
Summary
1-2 lines with finding count.
Example Output
### Findings
#### [High] Response Body Leak in HTTP Client
- **ID:** ERR-001
- **Location:** `internal/client/api.go:45`
- **Impact:** Connection pool exhaustion — resp.Body not closed on error path
- **Evidence:** `resp, err := client.Do(req)` at L42; if `resp.StatusCode != 200` at L44, function returns error at L46 without closing resp.Body. Body only closed on happy path at L52.
- **Recommendation:** Move defer immediately after nil-error check:
```go
resp, err := client.Do(req)
if err != nil { return err }
defer resp.Body.Close()- Action: must-fix
[High] Missing rows.Err() After Iteration
- ID: ERR-002
- Location:
internal/repo/order.go:78 - Impact: Silent data truncation — if iteration breaks due to network error, partial results returned without error
- Evidence:
for rows.Next() { ... }loop at L73-80 exits without checkingrows.Err() - Recommendation: Add after loop:
if err := rows.Err(); err != nil { return nil, fmt.Errorf("iterating orders: %w", err) } - Action: must-fix
Suppressed Items
[Suppressed] json.Marshal Error Ignored
- Reason:
json.Marshal(config)at config.go:30 —configisAppConfigstruct with only primitive fields. Anti-example: "known-safe struct with no interface fields"
Execution Status
- Go version: 1.21
- Grep pre-scan: 5/12 items hit, 2 confirmed as findings
- go test: PASS
- Excluded (generated): None
- References loaded: go-error-and-quality.md, go-api-http-checklist.md, go-database-patterns.md
Summary
2 High findings (response body leak, missing rows.Err). No Medium findings.
## No-Finding Case
If no issues found: state `No error handling findings identified.` Still output Execution Status.
## Load References Selectively
| Reference | Load When |
|-----------|-----------|
| `references/go-error-and-quality.md` | Always (error handling sections) |
| `references/go-api-http-checklist.md` | Code involves net/http, handlers, gin/echo/chi, gRPC |
| `references/go-database-patterns.md` | Code involves database/sql, pgx, sqlx, gorm, ent |
| `references/go-review-anti-examples.md` | Always |
## Review Discipline
- **Error handling, nil safety, failure-path integrity only** — not security, concurrency, performance, style, tests, or logic
- For every function call: **"what happens when it fails?"**
- Execute ALL 12 checklist items without skipping
- Server handler `r.Body`: do NOT require manual Close (framework handles it)
- Client `resp.Body`: MUST be closed on all pathsDoes it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

