gastownhall/beads · error

ErrQuery

ErrQuery

Error message

query error

What it means

ErrQuery is the dolt storage layer's sentinel for database query failures — the SQL SELECT itself failed (as opposed to scanning rows or executing writes). wrapQueryError embeds it in the error chain so callers can classify with errors.Is.

Source

Thrown at internal/storage/dolt/errors.go:25

	"os"
	"path/filepath"
	"strings"

	mysql "github.com/go-sql-driver/mysql"

	"github.com/steveyegge/beads/internal/storage"
	"github.com/steveyegge/beads/internal/storage/dberrors"
)

// Sentinel errors for the dolt storage layer.
// These complement the storage-level sentinels (storage.ErrNotFound, etc.)
// with dolt-specific error types.
var (
	// ErrTransaction indicates a transaction begin/commit/rollback failure.
	ErrTransaction = errors.New("transaction error")

	// ErrQuery indicates a database query failure.
	ErrQuery = errors.New("query error")

	// ErrScan indicates a failure scanning database rows into Go values.
	ErrScan = errors.New("scan error")

	// ErrExec indicates a database exec (INSERT/UPDATE/DELETE) failure.
	ErrExec = errors.New("exec error")

	// ErrDanglingReference indicates that the pre-push integrity check detected
	// missing chunks in the local Dolt noms store. The push was aborted to
	// prevent propagating the corruption to the remote. Run bd dolt verify
	// to diagnose and recover.
	ErrDanglingReference = errors.New("dangling chunk reference")

	// ErrFSCKTimeout indicates that the pre-push integrity check (dolt fsck) did
	// not complete within the configured timeout. The push was aborted without
	// verifying chunk integrity — the store is not necessarily corrupt. Large
	// stores can be shrunk with `dolt gc` (or `CALL DOLT_GC()` on a running
	// sql-server); the timeout can be raised via the BEADS_FSCK_TIMEOUT

View on GitHub (pinned to 71377f2769)

Solutions

  1. Unwrap and inspect the underlying error: errors.As(err, &mysql.MySQLError) for the MySQL error number
  2. Check server reachability and that the right database is being served (bd dolt status, bd doctor)
  3. If the error is 'table doesn't exist' (1146), run migrations or bd bootstrap for a fresh clone/branch-switch
  4. Retry on transient causes (connection reset, context deadline) once the connection is healthy

Example fix

// before
issues, err := store.List(ctx) // 'query error: ...' — cause unknown
// after
issues, err := store.List(ctx)
if err != nil {
    var mysqlErr *mysql.MySQLError
    if errors.As(err, &mysqlErr) && mysqlErr.Number == 1146 {
        return nil, fmt.Errorf("database not migrated; run bd bootstrap: %w", err)
    }
    return nil, err
}
Defensive patterns

Strategy: type-guard

Type guard

func isQueryError(err error) bool {
    return errors.Is(err, dolt.ErrQuery)
}
func isTableNotExist(err error) bool {
    var mysqlErr *mysql.MySQLError
    return errors.As(err, &mysqlErr) && mysqlErr.Number == 1146
}

Try / catch

if err := store.Get(ctx, id); err != nil {
    switch {
    case errors.Is(err, storage.ErrNotFound):
        return nil, err
    case errors.Is(err, dolt.ErrQuery) && isTableNotExist(err):
        return nil, fmt.Errorf("run bd bootstrap / migrate: %w", err)
    case errors.Is(err, dolt.ErrQuery):
        return nil, fmt.Errorf("query failed; check server health: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Any dolt-backed read whose db.QueryContext/QueryRowContext returns an error: connection refused or dropped, table doesn't exist (1146, e.g. pre-migration database), syntax/schema mismatch after version upgrade, server timeout, or context cancellation mid-query.

Common situations: Pointing bd at a server serving a different data directory (wrong database); database not yet migrated (missing tables); server restarted or moved ports; transient network failure between client and dolt sql-server.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/94b4e5f9869b3f17. Report an issue: GitHub.