gastownhall/beads · error
failed to open long-timeout connection: %w
Error message
failed to open long-timeout connection: %w
What it means
After parsing the DSN, execWithLongTimeout opens a dedicated single-connection pool via sql.Open. This error wraps sql.Open failure — almost always a driver-level configuration problem, since sql.Open does not establish a connection eagerly. The wrapped err names the driver/config problem.
Source
Thrown at internal/storage/dolt/store.go:2245
// 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()
}
// execWithLongTimeoutNoTx executes a long-running Dolt stored procedure without
// an explicit transaction. Push operations do not need the pull/merge conflict
// handling above, and DOLT_PUSH has diverged from direct `dolt push` behavior
// when wrapped in a SQL transaction.View on GitHub (pinned to 71377f2769)
Solutions
- Ensure the go-sql-driver/mysql package is imported for side effects
- Fix the underlying DSN error reported by the wrapped error
- Retry; if persistent, restart the daemon to rebuild connStr
Example fix
// before
import "database/sql"
// after
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
) Defensive patterns
Strategy: try-catch
Validate before calling
// ensure driver registered at init
import _ "github.com/go-sql-driver/mysql"
if _, err := mysql.ParseDSN(connStr); err != nil { return err } Try / catch
if err != nil {
if strings.Contains(err.Error(), "failed to open long-timeout connection") {
// check driver import + DSN formatting
}
return err
} Prevention
- Import mysql driver for side effects in every binary
- Format DSN only via cfg.FormatDSN()
- Add a startup self-test opening a throwaway sql.DB
- Pin driver version in go.mod
When it happens
Trigger: Calling execWithLongTimeout when sql.Open("mysql", cfg.FormatDSN()) errors — unknown driver name (driver not registered) or invalid formatted DSN.
Common situations: Missing/blank mysql driver import (driver not registered); corrupted DSN post-format; test environments without driver init.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- dolt server connection failed: %w
- failed to open migration connection: %w
- no database connection available (%s)
- dolt server unreachable at %s:%d (is dolt sql-server running
- failed to open server connection: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/1da634ac819eb8ad.
Report an issue: GitHub.