{"record":{"id":"4ed7af22b3939c62","repo":"gastownhall/beads","slug":"failed-to-open-migration-connection-w","errorCode":null,"errorMessage":"failed to open migration connection: %w","messagePattern":"failed to open migration connection: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/store.go","lineNumber":2749,"sourceCode":"\t}\n\tdefer migDB.Close()\n\treturn initSchemaOnDBWithRetry(ctx, migDB)\n}\n\n// openMigrationDB opens a one-off connection pool for schema migrations with no\n// read/write timeout. Migrations may run far longer than the default 10s pool\n// timeout, and timing out part-way leaves the database in a dirty, half-migrated\n// state. The single connection is closed by the caller once migration completes.\nfunc (s *DoltStore) openMigrationDB() (*sql.DB, error) {\n\tcfg, err := mysql.ParseDSN(s.connStr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse DSN for migration connection: %w\", err)\n\t}\n\tcfg.ReadTimeout = 0\n\tcfg.WriteTimeout = 0\n\tdb, err := sql.Open(\"mysql\", cfg.FormatDSN())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to open migration connection: %w\", err)\n\t}\n\tdb.SetMaxOpenConns(1)\n\treturn db, nil\n}\n\n// rebuildPoolAfterMigration replaces the main connection pool (s.db) after a\n// migrating open. Migrations run over a separate one-off pool\n// (openMigrationDB); a connection already pooled in s.db before migrations\n// ran (e.g. the startup Ping in newServerMode) stays pinned to the\n// pre-migration Dolt session root, so the first read through it returns 0\n// rows / table-not-found and does not self-heal on retry (be-itm5). A\n// non-migrating open (applied == 0 — the common re-open-of-an-\n// already-migrated-database path) has no stale state to fix and must return\n// before touching s.db or dialing anything.\nfunc (s *DoltStore) rebuildPoolAfterMigration(ctx context.Context, applied int) error {\n\tif applied == 0 {\n\t\treturn nil\n\t}","sourceCodeStart":2731,"sourceCodeEnd":2767,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/store.go#L2731-L2767","documentation":"After successfully parsing the DSN, openMigrationDB calls sql.Open(\"mysql\", cfg.FormatDSN()); this error wraps that failure. sql.Open mostly validates driver registration and DSN format, so failures here are rare and indicate the mysql driver is not registered or the formatted DSN is still invalid.","triggerScenarios":"sql.Open returning an error when the mysql driver was never imported/registered (missing import of the driver package in the binary), or FormatDSN producing an invalid string from corrupted cfg fields.","commonSituations":"Refactoring removed the blank import _ \"github.com/go-sql-driver/mysql\" so the driver is unregistered; building with a driver-less storage build tag; programmatically corrupted cfg (empty host, invalid timeout strings).","solutions":["Ensure the mysql driver is imported somewhere in the binary: import _ \"github.com/go-sql-driver/mysql\"","Print/inspect cfg.FormatDSN() for malformed output and fix the source config","Verify the build includes the mysql driver (not an alternative pure-build without it)"],"exampleFix":"// before\nimport (\n    \"database/sql\"\n)\n// after\nimport (\n    \"database/sql\"\n    _ \"github.com/go-sql-driver/mysql\"\n)","handlingStrategy":"validation","validationCode":"// fail fast at startup if the mysql driver isn't registered\nif db, err := sql.Open(\"mysql\", \"user:pass@tcp(127.0.0.1:3306)/probe\"); err != nil {\n    panic(fmt.Sprintf(\"mysql driver missing: %v\", err))\n} else {\n    db.Close()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always blank-import the driver: _ \"github.com/go-sql-driver/mysql\"","Add a startup smoke test that opens and closes a connection","Avoid build tags that strip the mysql driver from the binary"],"tags":["go","mysql","driver","database"],"backgroundTag":"sql-driver-not-registered","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}