gastownhall/beads · error

failed to open ignored tx connection: %w

Error message

failed to open ignored tx connection: %w

What it means

beginIgnoredTxOnBranch falls back to a dedicated single-connection pool (sql.Open("mysql", s.connStr)) when no warm connection can be safely borrowed. This error wraps sql.Open failing — which for the go-sql-driver/mysql means the DSN could not be parsed or the driver is not registered, not that the network failed (dialing happens at Conn).

Source

Thrown at internal/storage/dolt/transaction.go:323

	// fallback below, this path never switches the session's branch — see
	// beginBorrowedTx for the pool invariant it preserves.
	if conn := s.borrowConnForIgnoredTx(ctx); conn != nil {
		tx, err := beginBorrowedTx(ctx, conn, branch)
		if err == nil {
			return func() { _ = conn.Close() }, tx, nil
		}
		// A stale pooled connection or a session on another branch: a fresh
		// dial always worked before, so discard this one (its session state is
		// untouched) and fall through to the fallback.
		_ = conn.Close()
	}

	// Fallback: a dedicated single-connection pool, paying the fresh dial the
	// borrow path exists to avoid.
	doltMetrics.ignoredTxFreshPool.Add(ctx, 1)
	db, err := sql.Open("mysql", s.connStr)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to open ignored tx connection: %w", err)
	}
	db.SetMaxOpenConns(1)

	conn, err := db.Conn(ctx)
	if err != nil {
		_ = db.Close()
		return nil, nil, fmt.Errorf("failed to acquire ignored tx connection: %w", err)
	}

	tx, err = beginTxOnConn(ctx, conn, branch)
	if err != nil {
		_ = conn.Close()
		_ = db.Close()
		return nil, nil, err
	}

	return func() { _ = conn.Close(); _ = db.Close() }, tx, nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Print/inspect s.connStr and validate the DSN format (user:pass@tcp(host:port)/db?params)
  2. Ensure the mysql driver is imported: `_ "github.com/go-sql-driver/mysql"`
  3. Escape DSN components built from config/env (url.QueryEscape credentials, validate host:port)
  4. Compare against the DSN used for the main pool (which works) and diff parameters

Example fix

// before
connStr := fmt.Sprintf("%s:%s@tcp(%s)/%s", user, pass, host, db) // pass may contain @ or :
// after
connStr := fmt.Sprintf("%s:%s@tcp(%s)/%s", url.QueryEscape(user), url.QueryEscape(pass), host, db)
Defensive patterns

Strategy: validation

Validate before calling

if _, err := mysql.ParseDSN(connStr); err != nil { return fmt.Errorf("bad DSN: %w", err) }

Prevention

When it happens

Trigger: Malformed or corrupted s.connStr (bad DSN parameters, unescaped characters); the mysql driver failing to register (blank import removed); DSN built dynamically with invalid host/port/params.

Common situations: Config or environment supplying a bad Dolt SQL DSN (e.g. spaces, bad timeout params); refactors dropping the `_ "github.com/go-sql-driver/mysql"` import; constructing the DSN from user input without escaping.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/9a41fcc2ddcb9a0e. Report an issue: GitHub.