{"record":{"id":"4a7cf3994f767890","repo":"gastownhall/beads","slug":"begin-tx-w","errorCode":null,"errorMessage":"begin tx: %w","messagePattern":"begin tx: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/events.go","lineNumber":20,"sourceCode":"\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/steveyegge/beads/internal/storage\"\n\t\"github.com/steveyegge/beads/internal/storage/issueops\"\n\t\"github.com/steveyegge/beads/internal/types\"\n)\n\n// AddComment adds a comment event to an issue\nfunc (s *DoltStore) AddComment(ctx context.Context, issueID, actor, comment string) error {\n\treturn s.withCircuitWrite(ctx, func(ctx context.Context) error {\n\t\tisWisp := s.isActiveWisp(ctx, issueID)\n\t\ttx, err := s.db.BeginTx(ctx, nil)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"begin tx: %w\", err)\n\t\t}\n\t\tdefer func() { _ = tx.Rollback() }()\n\n\t\tclearJournalScope := s.scopeEventsJournalTransaction(tx)\n\t\tdefer clearJournalScope()\n\n\t\tif err := issueops.AddCommentEventInTx(ctx, tx, issueID, actor, comment); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := s.commitSQLTx(ctx, \"commit add comment event\", tx); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif isWisp {\n\t\t\treturn nil\n\t\t}\n\t\treturn s.doltAddAndCommit(ctx, []string{\"events\"}, fmt.Sprintf(\"bd: comment %s\", issueID))\n\t})\n}","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/events.go#L2-L38","documentation":"AddComment fails when db.BeginTx cannot start a database transaction for the comment write. This means the connection to the Dolt backend is broken, the pool is exhausted, or the context was canceled before the transaction began. The underlying driver error is wrapped for errors.Is inspection.","triggerScenarios":"Calling AddComment (bd comment/create flows) when the Dolt sql-server is not running, the connection pool was closed, the context deadline expired, or too many concurrent writers exhausted connections.","commonSituations":"Dolt server crashed or was restarted while a bd process was running; long-running bd command had its context canceled by the user; heavy parallel scripts opening many simultaneous writes; network/timeout to a remote Dolt server.","solutions":["Verify the Dolt backend is running (`bd doctor` or check dolt sql-server) and restart bd to rebuild the pool.","If the error is context.DeadlineExceeded, increase the timeout or check why the operation is slow.","Reduce concurrent bd processes/scripts writing to the same repo simultaneously.","If the database file path is wrong/unreachable, fix the config (storage path) and re-open."],"exampleFix":"// before: no timeout on comment write\nctx := context.Background()\nerr := store.AddComment(ctx, issueID, actor, text)\n// after: bounded context so begin-tx can't hang forever\nctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)\ndefer cancel()\nerr := store.AddComment(ctx, issueID, actor, text)","handlingStrategy":"retry","validationCode":"// Go: probe connectivity before comment writes\nctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)\ndefer cancel()\nif err := s.db.PingContext(ctx); err != nil {\n\treturn fmt.Errorf(\"database unreachable: %w\", err)\n}","typeGuard":"func IsBeginTxError(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"begin tx\")\n}","tryCatchPattern":"err := store.AddComment(ctx, issueID, actor, text)\nif err != nil && strings.Contains(err.Error(), \"begin tx\") {\n\t// backend down or context canceled: reconnect and retry once\n\ttime.Sleep(200 * time.Millisecond)\n\treturn store.AddComment(ctx, issueID, actor, text)\n}","preventionTips":["Health-check the Dolt backend (Ping) before write-heavy operations.","Use bounded contexts so BeginTx cannot hang indefinitely.","Ensure only one bd process writes at a time to avoid pool exhaustion.","Restart bd after Dolt server restarts to discard stale pooled connections."],"tags":["database","dolt","transaction","begin","connection"],"backgroundTag":"begin-transaction-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}