gastownhall/beads · error

probing database %q existence: %w

Error message

probing database %q existence: %w

What it means

This error wraps a failure from the information_schema.schemata probe that selectTargetDatabase uses to check whether the target Dolt database exists before issuing a USE. The probe is deliberately an always-succeeds query: on Dolt, a failing statement (like a USE of a missing database) pins the pooled session to a stale catalog snapshot, poisoning the connection. The %w carries the underlying driver error from the schemata COUNT query.

Source

Thrown at internal/storage/schema/converged.go:143

// its life (be-bv7x). Probe with a query that always succeeds, then act.
func selectTargetDatabase(ctx context.Context, db DBConn, databaseName string, selector DatabaseSelector) (bool, string, error) {
	var current sql.NullString
	if err := db.QueryRowContext(ctx, "SELECT DATABASE()").Scan(&current); err != nil {
		return false, "", fmt.Errorf("reading current database: %w", err)
	}
	if current.Valid && current.String == databaseName {
		return true, "", nil
	}
	if selector == nil {
		return false, "", nil
	}

	var exists int
	if err := db.QueryRowContext(ctx,
		"SELECT COUNT(*) FROM information_schema.schemata WHERE schema_name = ?",
		databaseName,
	).Scan(&exists); err != nil {
		return false, "", fmt.Errorf("probing database %q existence: %w", databaseName, err)
	}
	if exists == 0 {
		return false, "", nil
	}

	quoted, err := selector(ctx, db, databaseName)
	if err != nil {
		return false, "", fmt.Errorf("selecting database %q: %w", databaseName, err)
	}
	if quoted == "" {
		return false, "", fmt.Errorf("selecting database %q: selector returned no quoted name", databaseName)
	}
	return true, quoted, nil
}

// migrationLockFree reports whether the database-scoped migration lock is
// currently unheld. IS_FREE_LOCK is a read: it never queues, never acquires,
// and costs one round trip, which is the entire point — the fast path exists

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check connection health: ping the server and verify the Dolt sql-server is up before retrying bd
  2. Inspect the wrapped (%w) driver error for the root cause (EOF, connection refused, context deadline)
  3. Retry the operation — the probe is read-only and safe to re-run
  4. If context timeouts recur, increase the timeout on bd's database connection settings

Example fix

// before: blind retry loop on any failure
if err := probe(ctx); err != nil { return err }
// after: detect dead connection and reconnect/retry
if err := probe(ctx); err != nil {
    if dberrors.IsConnErr(err) { db = reopen(ctx); continue }
    return err
}
Defensive patterns

Strategy: retry

Validate before calling

// before relying on the probe, confirm the server is reachable
if err := db.PingContext(ctx); err != nil {
    return fmt.Errorf("dolt server unreachable: %w", err)
}

Try / catch

if _, err := alreadyConverged(ctx, db, name, sel); err != nil {
    var connErr *net.OpError
    if errors.As(err, &connErr) || errors.Is(err, context.DeadlineExceeded) {
        // transient: retry with backoff
    }
    return err
}

Prevention

When it happens

Trigger: The SELECT COUNT(*) FROM information_schema.schemata WHERE schema_name = ? query itself fails — the SQL connection is broken/dropped mid-probe, the server rejects the query, the context is cancelled, or the driver returns an unexpected error. Not triggered when the database simply doesn't exist (that returns exists==0, no error).

Common situations: Dolt sql-server restarted or network blipped between pooled calls; connection idle-timed out by the server; context deadline exceeded during a slow open; permissions preventing read of information_schema on a restricted server.

Related errors


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