{"record":{"id":"4ce8765c5b159182","repo":"gastownhall/beads","slug":"failed-to-set-dolt-force-transaction-commit-w","errorCode":null,"errorMessage":"failed to set dolt_force_transaction_commit: %w","messagePattern":"failed to set dolt_force_transaction_commit: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/store.go","lineNumber":4386,"sourceCode":"\ttx, err := db.BeginTx(ctx, nil)\n\tif err != nil {\n\t\treturn pullReport{}, fmt.Errorf(\"failed to begin transaction: %w\", err)\n\t}\n\n\t// Allow commits with conflicts so we can inspect and resolve them.\n\tif _, err := tx.ExecContext(ctx, \"SET @@dolt_allow_commit_conflicts = 1\"); err != nil {\n\t\t_ = tx.Rollback()\n\t\treturn pullReport{}, fmt.Errorf(\"failed to set dolt_allow_commit_conflicts: %w\", err)\n\t}\n\t// bd-6dnrw.4: a merge that violates a foreign key (e.g. one clone deleted\n\t// an issue while another inserted a child row referencing it) rolls the\n\t// whole transaction back before it can be inspected. Let it land in the\n\t// working set instead so tryRepairFKCascadeViolations can apply the\n\t// cascade semantics; the violation check before tx.Commit() below refuses\n\t// to commit anything the repair did not fully clear.\n\tif _, err := tx.ExecContext(ctx, \"SET @@dolt_force_transaction_commit = 1\"); err != nil {\n\t\t_ = tx.Rollback()\n\t\treturn pullReport{}, fmt.Errorf(\"failed to set dolt_force_transaction_commit: %w\", err)\n\t}\n\n\t// DOLT_PULL's row is the engine's only in-band account of what the pull\n\t// did: `dolt pull` on the CLI exits 0 whether it merged or was already up\n\t// to date, and so does this CALL. Capturing it costs nothing — the drain\n\t// is identical — and it is the difference between a caller that knows\n\t// nothing arrived and one that only knows no error occurred (ga-bq9zd).\n\tpullRow, pullErr := schema.CallReturningRow(ctx, tx, query, args...)\n\treport := parseMergeReport(pullRow)\n\n\t// GH#3144: When DOLT_PULL fails because upstream branch tracking is not\n\t// configured in repo_state.json (common when remote was added via\n\t// bd dolt remote add rather than bd bootstrap/dolt clone), fall back to\n\t// DOLT_FETCH + DOLT_MERGE which does not require tracking config.\n\tif pullErr != nil && isBranchTrackingError(pullErr) {\n\t\tif err := schema.DrainCall(ctx, tx, \"CALL DOLT_FETCH(?, ?)\", remote, s.branch); err != nil {\n\t\t\t_ = tx.Rollback()\n\t\t\treturn pullReport{}, fmt.Errorf(\"fetch from %s/%s: %w\", remote, s.branch, err)","sourceCodeStart":4368,"sourceCodeEnd":4404,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/store.go#L4368-L4404","documentation":"Thrown when the store fails to execute `SET @@dolt_force_transaction_commit = 1` on the pull transaction. Dolt refuses to commit a transaction that leaves commit conflicts; this session variable is set so the pull can land a merge with conflicts into the working set where bd can inspect and repair it. If the SET itself fails, the transaction is rolled back and the pull aborts with this wrapped cause.","triggerScenarios":"During DoltStore pull operations that execute `SET @@dolt_force_transaction_commit = 1` via tx.ExecContext and the statement returns an error — e.g. the connection dropped mid-pull, the Dolt server rejected the session variable, or a context timeout canceled the query.","commonSituations":"Dolt server restarts or connection resets during `bd dolt pull`; an old Dolt engine version that does not recognize dolt_force_transaction_commit; context deadline exceeded on a slow pull against a large remote.","solutions":["Retry the pull — transient connection drops are the most common cause","Check the wrapped cause: if 'unknown variable', upgrade Dolt to a version supporting dolt_force_transaction_commit","Verify the Dolt server is reachable and not restarting (check server logs)","Increase the context timeout for the pull operation"],"exampleFix":"// before\nif _, err := tx.ExecContext(ctx, \"SET @@dolt_force_transaction_commit = 1\"); err != nil {\n    _ = tx.Rollback()\n    return pullReport{}, fmt.Errorf(\"failed to set dolt_force_transaction_commit: %w\", err)\n}\n// after\nctx, cancel := context.WithTimeout(ctx, 5*time.Minute)\ndefer cancel()\nif _, err := tx.ExecContext(ctx, \"SET @@dolt_force_transaction_commit = 1\"); err != nil {\n    _ = tx.Rollback()\n    return pullReport{}, fmt.Errorf(\"failed to set dolt_force_transaction_commit: %w\", err)\n}","handlingStrategy":"retry","validationCode":"// Before pulling, confirm the Dolt engine supports the session variable\nrows, err := db.Query(\"SELECT @@dolt_force_transaction_commit IS NOT NULL\")\nif err != nil {\n    // 'unknown variable' => upgrade Dolt before pulling\n}","typeGuard":null,"tryCatchPattern":"var pullErr error\nfor attempt := 0; attempt < 3; attempt++ {\n    pullErr = store.Pull(ctx)\n    if pullErr == nil || !strings.Contains(pullErr.Error(), \"dolt_force_transaction_commit\") {\n        break\n    }\n    time.Sleep(time.Duration(attempt+1) * time.Second)\n}","preventionTips":["Keep the Dolt engine version current so all session variables are recognized","Use generous context timeouts for pull operations","Monitor Dolt server uptime; avoid pulls during restarts"],"tags":["dolt","sql","transaction","pull"],"backgroundTag":"dolt-session-variable-set-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}