{"record":{"id":"1da634ac819eb8ad","repo":"gastownhall/beads","slug":"failed-to-open-long-timeout-connection-w","errorCode":null,"errorMessage":"failed to open long-timeout connection: %w","messagePattern":"failed to open long-timeout connection: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/store.go","lineNumber":2245,"sourceCode":"// it cannot expose conflict-resolution tables to the caller.\n//\n// Audited for be-b0am's fresh-connection branch hazard: safe — but the two\n// callers are safe for different reasons, so the annotation names both.\n// federation.go's CALL DOLT_PUSH(?, ?) names the refspec explicitly. Its\n// CALL DOLT_FETCH(?) passes only the remote: with no refspec argument dolt\n// falls back to the remote's configured refspecs (ParseRefSpecs ->\n// GetRefSpecs), which are remote config rather than session state, and a\n// fetch writes only remote-tracking refs, never the working branch. Neither\n// depends on this fresh connection's default checkout.\nfunc (s *DoltStore) execWithLongTimeout(ctx context.Context, query string, args ...any) error {\n\tcfg, err := mysql.ParseDSN(s.connStr)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse DSN for long-timeout connection: %w\", err)\n\t}\n\tcfg.ReadTimeout = 5 * time.Minute\n\tdb, err := sql.Open(\"mysql\", cfg.FormatDSN())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to open long-timeout connection: %w\", err)\n\t}\n\tdefer db.Close()\n\tdb.SetMaxOpenConns(1)\n\ttx, err := db.BeginTx(ctx, nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to begin transaction: %w\", err)\n\t}\n\tif _, err := tx.ExecContext(ctx, query, args...); err != nil {\n\t\t_ = tx.Rollback()\n\t\treturn err\n\t}\n\treturn tx.Commit()\n}\n\n// execWithLongTimeoutNoTx executes a long-running Dolt stored procedure without\n// an explicit transaction. Push operations do not need the pull/merge conflict\n// handling above, and DOLT_PUSH has diverged from direct `dolt push` behavior\n// when wrapped in a SQL transaction.","sourceCodeStart":2227,"sourceCodeEnd":2263,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/store.go#L2227-L2263","documentation":"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.","triggerScenarios":"Calling execWithLongTimeout when sql.Open(\"mysql\", cfg.FormatDSN()) errors — unknown driver name (driver not registered) or invalid formatted DSN.","commonSituations":"Missing/blank mysql driver import (driver not registered); corrupted DSN post-format; test environments without driver init.","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"],"exampleFix":"// before\nimport \"database/sql\"\n// after\nimport (\n    \"database/sql\"\n    _ \"github.com/go-sql-driver/mysql\"\n)","handlingStrategy":"try-catch","validationCode":"// ensure driver registered at init\nimport _ \"github.com/go-sql-driver/mysql\"\nif _, err := mysql.ParseDSN(connStr); err != nil { return err }","typeGuard":null,"tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"failed to open long-timeout connection\") {\n        // check driver import + DSN formatting\n    }\n    return err\n}","preventionTips":["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"],"tags":["database","driver","connection","mysql"],"backgroundTag":"sql-open-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}