{"record":{"id":"85d212f82f3b31a6","repo":"gastownhall/beads","slug":"failed-to-open-server-connection-w","errorCode":null,"errorMessage":"failed to open server connection: %w","messagePattern":"failed to open server connection: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/doctor/dolt.go","lineNumber":61,"sourceCode":"\t// resolved runtime port — matching the CRUD path. Env var BEADS_DOLT_PASSWORD\n\t// still takes precedence inside GetDoltServerPasswordForPort. Without this,\n\t// externally-hosted Dolt servers that keep credentials in\n\t// ~/.config/beads/credentials fail doctor checks with \"Access denied\" while\n\t// regular CRUD commands succeed (bd-h5k7).\n\tpassword := cfg.GetDoltServerPasswordForPort(port)\n\n\tconnStr := doltutil.ServerDSN{\n\t\tHost:     host,\n\t\tPort:     port,\n\t\tUser:     user,\n\t\tPassword: password,\n\t\tDatabase: database,\n\t\tTLS:      cfg.GetDoltServerTLS(),\n\t}.String()\n\n\tdb, err := sql.Open(\"mysql\", connStr)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to open server connection: %w\", err)\n\t}\n\n\tdb.SetMaxOpenConns(2)\n\tdb.SetMaxIdleConns(1)\n\tdb.SetConnMaxLifetime(30 * time.Second)\n\n\t// Verify connectivity\n\tctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\n\tdefer cancel()\n\n\tif err := db.PingContext(ctx); err != nil {\n\t\t_ = db.Close() // Best effort cleanup\n\t\treturn nil, nil, fmt.Errorf(\"server not reachable: %w\", err)\n\t}\n\n\treturn db, cfg, nil\n}\n","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/doctor/dolt.go#L43-L79","documentation":"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).","triggerScenarios":"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).","commonSituations":"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.","solutions":["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.","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.","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."],"exampleFix":"// before\nimport (\n    \"database/sql\"\n)\ndb, err := sql.Open(\"mysql\", connStr) // unknown driver \"mysql\"\n// after\nimport (\n    \"database/sql\"\n    _ \"github.com/go-sql-driver/mysql\"\n)\ndb, err := sql.Open(\"mysql\", connStr)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"db, err := openDoltDB(beadsDir)\nif err != nil {\n    var oe *net.OpError\n    if errors.As(err, &oe) {\n        // network-level issue vs DSN parse error\n    }\n    if strings.Contains(err.Error(), \"unknown driver\") {\n        // missing _ \"github.com/go-sql-driver/mysql\" import\n    }\n    return err\n}","preventionTips":["Ensure the go-sql-driver/mysql driver is imported wherever sql.Open(\"mysql\", ...) is called.","Keep config.yaml values (host, user, database) free of characters that break DSN syntax; escape passwords.","Validate config values early with a small parse of the resulting DSN format."],"tags":["dolt","mysql","sql","connection"],"backgroundTag":"sql-open-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}