gastownhall/beads · error

failed to open server connection: %w

Error message

failed to open server connection: %w

What it means

openDoltDB builds a mysql DSN from the resolved host/port/user/database/TLS settings and calls sql.Open("mysql", connStr). sql.Open only validates the DSN format and driver registration — it does not connect. This error wraps any failure sql.Open returns, meaning the constructed connection string was malformed or the driver failed to initialize, not that the server was unreachable (that is the separate ping error).

Source

Thrown at cmd/bd/doctor/dolt.go:61

	// resolved runtime port — matching the CRUD path. Env var BEADS_DOLT_PASSWORD
	// still takes precedence inside GetDoltServerPasswordForPort. Without this,
	// externally-hosted Dolt servers that keep credentials in
	// ~/.config/beads/credentials fail doctor checks with "Access denied" while
	// regular CRUD commands succeed (bd-h5k7).
	password := cfg.GetDoltServerPasswordForPort(port)

	connStr := doltutil.ServerDSN{
		Host:     host,
		Port:     port,
		User:     user,
		Password: password,
		Database: database,
		TLS:      cfg.GetDoltServerTLS(),
	}.String()

	db, err := sql.Open("mysql", connStr)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to open server connection: %w", err)
	}

	db.SetMaxOpenConns(2)
	db.SetMaxIdleConns(1)
	db.SetConnMaxLifetime(30 * time.Second)

	// Verify connectivity
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := db.PingContext(ctx); err != nil {
		_ = db.Close() // Best effort cleanup
		return nil, nil, fmt.Errorf("server not reachable: %w", err)
	}

	return db, cfg, nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped error for a DSN parse message; check .beads/config.yaml values (host, user, database, TLS) for invalid characters and quote/escape them.
  2. If the error says "unknown driver \"mysql\"", ensure the go-sql-driver/mysql package is imported (blank import in the driver setup) so sql.Open can find it.
  3. As a workaround, verify connection params independently: try connecting with a mysql client using the same host/port/user/database from config to confirm the values are sane.

Example fix

// before
import (
    "database/sql"
)
db, err := sql.Open("mysql", connStr) // unknown driver "mysql"
// after
import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)
db, err := sql.Open("mysql", connStr)
Defensive patterns

Strategy: try-catch

Try / catch

db, err := openDoltDB(beadsDir)
if err != nil {
    var oe *net.OpError
    if errors.As(err, &oe) {
        // network-level issue vs DSN parse error
    }
    if strings.Contains(err.Error(), "unknown driver") {
        // missing _ "github.com/go-sql-driver/mysql" import
    }
    return err
}

Prevention

When it happens

Trigger: Calling openDoltDB (via openDoltConn or querySQLRemotes) where sql.Open fails: malformed DSN produced from config values (bad characters in host/user/database), or the mysql driver not being registered (missing import of the go-sql-driver/mysql package).

Common situations: Config values containing characters that break DSN parsing (spaces, unescaped special chars in user/password); TLS setting producing an invalid DSN parameter; a refactor removing the driver's blank import so `mysql` is an unknown driver.

Related errors


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