{"record":{"id":"5932fc9d74df2607","repo":"gastownhall/beads","slug":"open-gc-connection-w","errorCode":null,"errorMessage":"open gc connection: %w","messagePattern":"open gc connection: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/server/doltserver.go","lineNumber":393,"sourceCode":"\t}\n\tvar rmErr error\n\tif s.pid != 0 {\n\t\trmErr = pidfile.Remove(s.rootDir, PIDFileName)\n\t\ts.pid = 0\n\t}\n\tif rmErr != nil {\n\t\trmErr = fmt.Errorf(\"server: DoltServer.Stop: remove pidfile: %w\", rmErr)\n\t}\n\treturn errors.Join(gcErr, waitErr, closeErr, rmErr)\n}\n\nfunc (s *DoltServer) runShutdownGC(ctx context.Context) (retErr error) {\n\tif s.database == \"\" || !s.Running(ctx) {\n\t\treturn nil\n\t}\n\tdb, err := sql.Open(\"mysql\", s.DSN(ctx, s.database, \"root\", \"\"))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"open gc connection: %w\", err)\n\t}\n\tdefer func() { retErr = errors.Join(retErr, db.Close()) }()\n\n\tconn, err := db.Conn(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"acquire gc connection: %w\", err)\n\t}\n\tdefer func() { retErr = errors.Join(retErr, conn.Close()) }()\n\n\tif err := versioncontrolops.DoltGC(ctx, conn); err != nil {\n\t\tretErr = errors.Join(retErr, err)\n\t}\n\tif _, err := conn.ExecContext(ctx, \"CALL DOLT_STATS_GC()\"); err != nil {\n\t\tretErr = errors.Join(retErr, fmt.Errorf(\"dolt_stats_gc: %w\", err))\n\t}\n\treturn retErr\n}\n","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/server/doltserver.go#L375-L411","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nimport \"database/sql\"\n// after\nimport (\n    \"database/sql\"\n    _ \"github.com/go-sql-driver/mysql\" // register \"mysql\" driver\n)","handlingStrategy":"validation","validationCode":"import (\n    _ \"github.com/go-sql-driver/mysql\" // ensure driver registered at init\n)\n// sanity-check DSN before Stop\nfunc validDSN(d string) bool {\n    cfg, err := mysql.ParseDSN(d)\n    return err == nil && cfg.DBName != \"\"\n}","typeGuard":null,"tryCatchPattern":"if err := server.Stop(ctx); err != nil {\n    var openErr error\n    if strings.Contains(err.Error(), \"open gc connection\") {\n        openErr = fmt.Errorf(\"shutdown GC unavailable, check mysql driver/DSN: %w\", err)\n    }\n    return openErr // or log-and-continue if GC is optional\n}","preventionTips":["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"],"tags":["go","mysql","dsn","shutdown","gc"],"backgroundTag":"sql-open-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}