gastownhall/beads · error
failed to parse DSN for long-timeout connection: %w
Error message
failed to parse DSN for long-timeout connection: %w
What it means
execWithLongTimeout re-parses the store's connection string with go-sql-driver/mysql.ParseDSN to build a dedicated 5-minute-read-timeout connection. This error wraps a DSN parse failure, meaning the stored connStr is malformed for the mysql driver.
Source
Thrown at internal/storage/dolt/store.go:2240
// readTimeout when the server performs network I/O to git remotes.
//
// The query is wrapped in an explicit transaction (BEGIN/COMMIT) so that
// DOLT_PULL merge operations succeed even when the server runs with
// autocommit=1. Without this, Dolt rejects merges under autocommit because
// it cannot expose conflict-resolution tables to the caller.
//
// Audited for be-b0am's fresh-connection branch hazard: safe — but the two
// callers are safe for different reasons, so the annotation names both.
// federation.go's CALL DOLT_PUSH(?, ?) names the refspec explicitly. Its
// CALL DOLT_FETCH(?) passes only the remote: with no refspec argument dolt
// falls back to the remote's configured refspecs (ParseRefSpecs ->
// GetRefSpecs), which are remote config rather than session state, and a
// fetch writes only remote-tracking refs, never the working branch. Neither
// depends on this fresh connection's default checkout.
func (s *DoltStore) execWithLongTimeout(ctx context.Context, query string, args ...any) error {
cfg, err := mysql.ParseDSN(s.connStr)
if err != nil {
return fmt.Errorf("failed to parse DSN for long-timeout connection: %w", err)
}
cfg.ReadTimeout = 5 * time.Minute
db, err := sql.Open("mysql", cfg.FormatDSN())
if err != nil {
return fmt.Errorf("failed to open long-timeout connection: %w", err)
}
defer db.Close()
db.SetMaxOpenConns(1)
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("failed to begin transaction: %w", err)
}
if _, err := tx.ExecContext(ctx, query, args...); err != nil {
_ = tx.Rollback()
return err
}
return tx.Commit()
}View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the DSN in bd dolt status / config and fix malformed parts
- Re-run bd init or restart bd dolt server to regenerate the DSN
- Escape or URL-encode special characters in the password
- Verify connection settings in .beads/metadata.json
Example fix
// before connStr := "user:p@ss!w0rd@tcp(localhost:3307)/db" // after connStr := "user:p%40ss%21w0rd@tcp(localhost:3307)/db"
Defensive patterns
Strategy: validation
Validate before calling
if _, err := mysql.ParseDSN(connStr); err != nil {
return fmt.Errorf("invalid DSN before long query: %w", err)
} Try / catch
err := store.execWithLongTimeout(ctx, q)
if err != nil {
var ue *mysql.MySQLError
if strings.Contains(err.Error(), "failed to parse DSN") {
// regenerate connStr
}
return err
} Prevention
- URL-encode special chars in DSN credentials
- Never hand-edit generated connection strings
- Validate DSNs at config load time
- Test DSN round-trip with ParseDSN/FormatDSN
When it happens
Trigger: Calling execWithLongTimeout when s.connStr cannot be parsed by mysql.ParseDSN — e.g. invalid URL format, unescaped special characters in password, or bad parameters.
Common situations: Password contains characters needing DSN escaping; manually edited config producing an invalid DSN; buildServerDSN producing a scheme mismatch (http vs tcp).
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse DSN for migration connection: %w
- failed to open MySQL connection: %w
- ensure global db: failed to open connection: %w
- flush: failed to open connection: %w
- open gc connection: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/480a15ad212ddab4.
Report an issue: GitHub.