ErrLookupBackground articles › "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained

"query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained

Wrapped SQL query failures — errors like "check remaining blockers from %s: %w", "failed to query orphaned dependencies: %w", or "Cannot fetch records for <Class>" — mean a SELECT or write issued by a library against its database backend (SQLite, Dolt, MySQL) failed at the driver or server level. Developers hit these when running CLI commands, imports, doctor-style repairs, or batch reads: the fix is to read the wrapped %w cause, which almost always points to a missing or unmigrated table, a schema drift after an upgrade, a lost connection, or a context that was cancelled mid-query.

Distilled from 112 documented records across 3 repositories.

Background

This family covers errors produced not by a library's own logic but by the database layer underneath it. A Go library opens a transaction, issues a SELECT, INSERT, or UPDATE through database/sql (QueryContext, QueryRowContext, Scan), and the driver or server rejects it. The library then wraps that raw driver error with a message naming the failing operation — sometimes the table involved — and returns it to the caller. The wrap pattern ("doing X from <table>: %w") is deliberate: it tells you which step of a multi-step operation failed while preserving the underlying error via %w so the real cause (missing table, lost connection, permission denied) is one unwrap away.

The most common producing layer is a storage repository inside an application or CLI tool. In the beads issue tracker, dozens of storage methods follow this shape: import paths wrap config writes and empty-database checks ("importing config %q: %w", "checking issue count: %w"), dependency-graph reads name the exact table that failed ("get dependency counts (dependents from %s): %w", "failed to get parent-child deps from %s: %w"), and repair/doctor commands wrap their data-gathering queries ("failed to query orphaned dependencies: %w", "failed to recompute is_blocked: %w"). On the Java side, Hadoop's state store shows the same family in a different language: any SQLException from fetching router state records becomes an IOException ("Cannot fetch records for <Class>") with the SQL exception as cause.

From the caller's side, these errors are usually abort-with-rollback. Because most of the failing queries run inside transactions — imports, ID generation, recompute passes — the surrounding transaction rolls back, leaving the database in its prior state and the operation safely retryable. Several libraries exploit this deliberately: a failed beads import leaves the database still empty, so rerunning is idempotent. The error message is therefore not a corruption report in most cases; it is a pre-operation environmental failure (schema, connectivity, permissions, timing) that stopped the operation before it could change anything.

The family varies in how much detail it surfaces. Some wrappers embed the table name ("get labels for issues from %s: %w") so you immediately know which table to inspect; others echo query arguments ("events since cursor (%v, %q) issue %q: %w") to make the failing query reproducible. Some libraries also define tolerated cases: an optional table that doesn't exist (for example beads' wisp_dependencies on pre-migration databases) is skipped gracefully, so the wrapped error fires only when the table exists but is broken, or when a required table is missing. Reading the wrapped cause is essential — the same wrapper can cover a table-not-exist, a connection reset, a lock timeout, a permission denial, or a context cancellation, and the remedies differ.

Common causes

What usually fixes it

Go deeper

Documented occurrences

…and 92 more across the corpus — use search.

Honest provenance: generated on 2026-08-30 from AI-assisted analysis of the linked records. See how records are made.