gastownhall/beads · warning

flush: failed to open connection: %w

Error message

flush: failed to open connection: %w

What it means

FlushWorkingSet wraps sql.Open("mysql", dsn) failure with this message when preparing its best-effort connection (as root, no password) to the running dolt server before shutdown. As with all sql.Open errors, this indicates a malformed DSN or unregistered driver, not an unreachable server — the ping step handles reachability separately. The function is best-effort: callers only log a warning if it fails.

Source

Thrown at internal/doltserver/doltserver.go:1575

	return nil
}

// FlushWorkingSet connects to the running Dolt server and commits any uncommitted
// working set changes across all databases. This prevents data loss when the server
// is about to be stopped or restarted. Returns nil if there's nothing to flush or
// if the server is not reachable (best-effort).
func FlushWorkingSet(host string, port int) error {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	dsn := doltutil.ServerDSN{
		Host: host,
		Port: port,
		User: "root",
	}.String()
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		return fmt.Errorf("flush: failed to open connection: %w", err)
	}
	defer db.Close()
	db.SetMaxOpenConns(1)
	db.SetConnMaxLifetime(10 * time.Second)

	if err := db.PingContext(ctx); err != nil {
		return fmt.Errorf("flush: server not reachable: %w", err)
	}

	// List all databases, skipping system databases
	rows, err := db.QueryContext(ctx, "SHOW DATABASES")
	if err != nil {
		return fmt.Errorf("flush: failed to list databases: %w", err)
	}
	var databases []string
	for rows.Next() {
		var name string
		if err := rows.Scan(&name); err != nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped error for 'invalid DSN' and correct the host value in bd config (alphanumeric hostname or IP only)
  2. Validate BEADS_DB_HOST / dolt.shared-server-host has no stray quotes, spaces, or scheme (no 'http://')
  3. If building a custom binary, ensure _ "github.com/go-sql-driver/mysql" is imported
  4. This is best-effort (uncommitted working-set changes may be lost); if it persists, commit work manually before bd dolt stop
  5. Retry the stop/restart — the failure may come from transient config reload

Example fix

// before: scheme in host corrupts the DSN
// host := "http://127.0.0.1"
// after: plain host only
host := "127.0.0.1"
Defensive patterns

Strategy: validation

Validate before calling

// Validate host is a clean hostname/IP before FlushWorkingSet builds its DSN
if net.ParseIP(host) == nil {
    if _, err := net.LookupHost(host); err != nil {
        return fmt.Errorf("configured dolt host %q is not a valid host", host)
    }
}
if strings.ContainsAny(host, "@:/() \t") {
    return fmt.Errorf("configured dolt host %q contains invalid DSN characters", host)
}

Try / catch

if err := doltserver.FlushWorkingSet(host, port); err != nil {
    // best-effort by design: log and continue shutdown, but flag possible data loss
    log.Printf("warning: working-set flush skipped (%v); uncommitted changes may remain", err)
}

Prevention

When it happens

Trigger: sql.Open("mysql", dsn) errors while building the root/no-password DSN from host and port — invalid characters in the configured host, or the mysql driver missing from the binary.

Common situations: A hand-edited config leaving stray characters in dolt.host; custom builds without the go-sql-driver/mysql import; automated tooling injecting malformed host values.

Related errors


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