gastownhall/beads · error
open gc connection: %w
Error message
open gc connection: %w
What it means
runShutdownGC opens a temporary sql.DB connection (driver "mysql") to the Dolt server using DSN(ctx, database, "root", "") to run shutdown garbage collection. This error wraps a failure from sql.Open — most commonly the MySQL driver registration or malformed DSN.
Source
Thrown at internal/storage/dbproxy/server/doltserver.go:393
}
var rmErr error
if s.pid != 0 {
rmErr = pidfile.Remove(s.rootDir, PIDFileName)
s.pid = 0
}
if rmErr != nil {
rmErr = fmt.Errorf("server: DoltServer.Stop: remove pidfile: %w", rmErr)
}
return errors.Join(gcErr, waitErr, closeErr, rmErr)
}
func (s *DoltServer) runShutdownGC(ctx context.Context) (retErr error) {
if s.database == "" || !s.Running(ctx) {
return nil
}
db, err := sql.Open("mysql", s.DSN(ctx, s.database, "root", ""))
if err != nil {
return fmt.Errorf("open gc connection: %w", err)
}
defer func() { retErr = errors.Join(retErr, db.Close()) }()
conn, err := db.Conn(ctx)
if err != nil {
return fmt.Errorf("acquire gc connection: %w", err)
}
defer func() { retErr = errors.Join(retErr, conn.Close()) }()
if err := versioncontrolops.DoltGC(ctx, conn); err != nil {
retErr = errors.Join(retErr, err)
}
if _, err := conn.ExecContext(ctx, "CALL DOLT_STATS_GC()"); err != nil {
retErr = errors.Join(retErr, fmt.Errorf("dolt_stats_gc: %w", err))
}
return retErr
}
View on GitHub (pinned to 71377f2769)
Solutions
- Check the generated DSN (log s.DSN(...)) for invalid characters, especially in the database name
- Ensure the mysql driver is linked via import _ "github.com/go-sql-driver/mysql"
- Confirm s.database is the correct non-empty database name; empty name skips GC entirely
- Retry Stop — transient DSN parsing is rare, but configuration errors are deterministic and must be fixed
Example fix
// before
import "database/sql"
// after
import (
"database/sql"
_ "github.com/go-sql-driver/mysql" // register "mysql" driver
) Defensive patterns
Strategy: validation
Validate before calling
import (
_ "github.com/go-sql-driver/mysql" // ensure driver registered at init
)
// sanity-check DSN before Stop
func validDSN(d string) bool {
cfg, err := mysql.ParseDSN(d)
return err == nil && cfg.DBName != ""
} Try / catch
if err := server.Stop(ctx); err != nil {
var openErr error
if strings.Contains(err.Error(), "open gc connection") {
openErr = fmt.Errorf("shutdown GC unavailable, check mysql driver/DSN: %w", err)
}
return openErr // or log-and-continue if GC is optional
} Prevention
- Blank-import the mysql driver in any binary that constructs DoltServer
- Validate the database name (no invalid DSN characters) at config load time
- Log the DSN (password redacted) once at startup to catch drift early
When it happens
Trigger: DoltServer.Stop invoked on a running server with a non-empty s.database, and sql.Open("mysql", dsn) returns an error — typically an invalid DSN (bad characters in database name/host) or the mysql driver not being registered in the binary.
Common situations: Database name containing characters needing DSN escaping; a blank-import of the mysql driver removed during refactoring so "mysql" is unknown; empty password/root user disallowed by config feeding into DSN.
Related errors
- ensure global db: failed to open connection: %w
- flush: failed to open connection: %w
- flush: server not reachable: %w
- acquire gc connection: %w
- dolt_stats_gc: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/5932fc9d74df2607.
Report an issue: GitHub.