{"record":{"id":"bfab3d51f8341e05","repo":"gastownhall/beads","slug":"release-merge-connection-w","errorCode":null,"errorMessage":"release merge connection: %w","messagePattern":"release merge connection: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/storage/dolt/store.go","lineNumber":4933,"sourceCode":"\tconn, err := s.db.Conn(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"acquire connection for merge: %w\", err)\n\t}\n\tconflicts, err = versioncontrolops.MergeWithStrategy(ctx, conn, branch, s.commitAuthorString(), strategy)\n\t// Release the pinned connection before the recompute: s.db's pool can be\n\t// configured with a single connection (setupTestStore's MaxOpenConns: 1\n\t// mirrors constrained production configs), and recomputeBlockedAfterPull\n\t// acquires its own connection — held past this point, conn would starve\n\t// it of the only one available.\n\tcloseErr := conn.Close()\n\tif len(conflicts) > 0 {\n\t\tspan.SetAttributes(attribute.Int(\"dolt.conflicts\", len(conflicts)))\n\t}\n\tif err != nil {\n\t\treturn conflicts, err\n\t}\n\tif closeErr != nil {\n\t\treturn conflicts, fmt.Errorf(\"release merge connection: %w\", closeErr)\n\t}\n\tif !s.readOnly {\n\t\tif rerr := s.recomputeBlockedAfterPull(ctx, preHead); rerr != nil {\n\t\t\treturn conflicts, fmt.Errorf(\"merge succeeded but is_blocked recompute failed: %w\", rerr)\n\t\t}\n\t}\n\treturn conflicts, nil\n}\n\n// RecomputeBlockedAfterMerge recomputes the denormalized is_blocked column\n// for the rows changed since fromCommit and commits the result — the hook a\n// caller that resolved merge conflicts itself must run after committing the\n// resolution (bd-578h9.11): conflicted merges skip the automatic recompute\n// because unresolved rows would feed it garbage, and nothing else covers the\n// merged-in writes. fromCommit is the pre-merge HEAD; empty degrades to a\n// full-graph recompute.\nfunc (s *DoltStore) RecomputeBlockedAfterMerge(ctx context.Context, fromCommit string) error {\n\treturn s.recomputeBlockedAfterPull(ctx, fromCommit)","sourceCodeStart":4915,"sourceCodeEnd":4951,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/store.go#L4915-L4951","documentation":"After a successful merge with a pinned connection, the code closes that connection before running the recompute so it doesn't starve a constrained pool. This error wraps a failure of that conn.Close() call. The merge succeeded and results are valid; only returning the connection to the pool failed, which is unusual (driver-level close error).","triggerScenarios":"MergeWithStrategy succeeded, then the deferred/explicit conn.Close() returned a non-nil error — typically a broken underlying connection (server closed it mid-merge lifecycle) or driver close failure.","commonSituations":"Dolt server restarted or dropped the session after the merge completed; network interruption; driver bugs on connections that experienced protocol errors.","solutions":["Treat the merge as successful — verify conflicts/results and continue; the pool will discard the bad connection.","Ping or validate pool health; database/sql removes dead connections automatically on subsequent use.","Check Dolt server logs for session drops/timeouts during merges.","If this recurs, upgrade the Dolt driver or raise conn max lifetime to recycle sessions proactively.","Retry the operation if subsequent recompute also failed."],"exampleFix":"// before\nif closeErr != nil { return conflicts, fmt.Errorf(\"release merge connection: %w\", closeErr) }\n// after\nif closeErr != nil {\n    log.Warn(\"merge connection close failed; pool will recycle\", \"err\", closeErr)\n} // don't fail the successful merge on a pool-release error","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"conflicts, closeErr := store.MergeWithStrategy(ctx, branch, strategy)\nif closeErr != nil {\n    // merge succeeded; pool release failed — log and continue, don't fail results\n    log.Warn(\"merge ok but connection release failed\", \"err\", closeErr)\n}\nif len(conflicts) > 0 { handleConflicts(conflicts) }","preventionTips":["Set ConnMaxLifetime below server wait_timeout to avoid dying sessions","Monitor Dolt server restarts and session drops","Treat conn.Close() errors as non-fatal when the operation itself succeeded","Keep the driver updated; close errors often trace to driver bugs"],"tags":["dolt","merge","connection-pool","resource-cleanup"],"backgroundTag":"connection-close-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}