Repository navigation
v4.6.0 — the Go 1.27 defect backlog
Go 1.27's standard-library delta is almost entirely noise for this stack. The value was the defects it exposed in rules the corpus already shipped: 31 corrections across 17 documents, six of them tier 1. No new pattern document, no version bump.
cfg.BaseURL was defined nowhere. go-email.md's tier-1 rule builds every emailed link from it, and no document said to add, parse, validate or set it — three consumers, zero definitions, including a checklist box. With no field to build from, the shortest path back to a working reset link is the r.Host line that document prints as the thing never to write. go-config.md now owns BASE_URL and the sender address, the two boot checks go-email.md already credited to it, and the check is on the scheme and the host rather than on err: url.Parse returns no error for evil.example, /reset, app.db or javascript:alert(1).
Two json/v2 failure modes nothing warned about. Marshal hands back the bytes it got through and a non-nil error where v1 handed back nil, so a MarshalWrite aimed at a ResponseWriter commits a 200 and half a body — measured, a recovering http.Error spliced its text into the broken JSON. And an error wrapping errors.ErrUnsupported is read by v2 as "use the default representation": a MarshalJSONTo written to redact a secret returned {"user":"ada","token":"hunter2"} with a nil error, while the []byte form errored loudly. The docs recommend the streaming form, so the recommended form is the unsafe one.
srv.URL is a real public domain, and this repository's own v4.4.0 migration created that. Under httptest.NewTestServer it becomes http://example.com as soon as anything uses the server, so http.Get(srv.URL) returned 200 with Server: cloudflare and IANA's Example Domain page — the test passing having asserted nothing. go-testing.md carries a tier-1 carve-out: a test never sends a request off this machine.
A leaked Rows wedges the single-writer pool forever. The corpus mandated SetMaxOpenConns(1) and never said defer rows.Close(), rows.Err() or defer tx.Rollback() anywhere. busy_timeout never fires because the wait is in Go's pool rather than in SQLite, and seven such defects on one file drew nothing from go vet or staticcheck -checks=all. Rules 8 and 9, plus the t.Cleanup on Stats().InUse that is the only thing which catches it mechanically.
LogValue protects only the top level, so a secret is now its own type carrying LogValue, String and MarshalText. make fmt never converged — go fix applies each fixer once and one rewrite exposes the next, and the import it adds to a single-import file is a second declaration gofmt keeps and only goimports merges.
Also: the WriteTimeout ladder is off by ReadTimeout (the canonical 10 s and 30 s ceiling a handler at 20 s, and past the deadline the client gets no status line while w.Write returns nil); the upload cap had no ReadTimeout half, so its tier-1 413 was unreachable; busy_timeout outranks the context deadline; the Go pin's note named one of five html/template escaper XSS advisories. Changes to the language had never been reviewed in four years of run logs — generic methods cannot implement a port interface, go fix's embedlit sets up a silent shadowing trap, and an iterator ignoring yield's result panics the caller's break.
Ten adversarial passes, 16 defects, the last two clean — every defect in the run's own new text, and four of them in the paragraph reporting the run. Reference: baseline-reference v4.6.0, 79 gates, make ci green.