{"record":{"id":"01d54f1eddb1aa56","repo":"gastownhall/beads","slug":"failed-to-parse-dsn-for-migration-connection-w","errorCode":null,"errorMessage":"failed to parse DSN for migration connection: %w","messagePattern":"failed to parse DSN for migration connection: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/store.go","lineNumber":2743,"sourceCode":"// per-database advisory lock, with retry for transient lock contention.\n// Implements storage.SchemaMigrator.\nfunc (s *DoltStore) ApplySchemaMigrations(ctx context.Context) (int, error) {\n\tmigDB, err := s.openMigrationDB()\n\tif err != nil {\n\t\treturn 0, err\n\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-","sourceCodeStart":2725,"sourceCodeEnd":2761,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/store.go#L2725-L2761","documentation":"openMigrationDB parses the store's connection string with mysql.ParseDSN before opening a dedicated long-timeout migration connection; this error wraps a DSN parse failure. It is a configuration problem: the connection string is malformed, not a server-side issue.","triggerScenarios":"Creating a DoltStore with s.connStr that mysql.ParseDSN rejects — malformed format (wrong scheme, bad net address, unterminated brackets), invalid parameter, or characters that need escaping (e.g. special chars in password like '@' or '/' unescaped).","commonSituations":"Password containing '@', '(', '/' or spaces placed raw into user:pass@tcp(...)/ DSN; env var BEADS_DSN missing or set to a non-DSN value; copy-pasted URI-style 'mysql://user:pass@host/db' which ParseDSN does not accept directly.","solutions":["Fix the DSN string: correct form is user:pass@tcp(host:port)/dbname?params","URL-escape or cfg-escape special characters in the password (e.g. use url.QueryEscape for the password portion when building the DSN)","Use mysql.Config + cfg.FormatDSN() in code instead of hand-writing the string","Check the environment variable / config file supplying the connection string for truncation or quoting artifacts"],"exampleFix":"// before\nconnStr := \"root:p@ss@tcp(localhost:3306)/beads\"\n// after\nconnStr := \"root:p%40ss@tcp(localhost:3306)/beads\"","handlingStrategy":"validation","validationCode":"// validate the DSN before constructing the store\nfunc validateDSN(connStr string) error {\n    cfg, err := mysql.ParseDSN(connStr)\n    if err != nil {\n        return fmt.Errorf(\"invalid DSN: %w\", err)\n    }\n    if cfg.DBName == \"\" {\n        return errors.New(\"DSN missing database name\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build DSNs with mysql.Config.FormatDSN(), never string concatenation","Escape special characters in passwords","Validate the env-provided DSN at startup, before first use","Store DSNs without surrounding quotes/whitespace from config files"],"tags":["go","mysql","configuration","dsn"],"backgroundTag":"invalid-dsn","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}