{"record":{"id":"c06effd5cd72bcf9","repo":"gastownhall/beads","slug":"db-update-s-clear-lease-w","errorCode":null,"errorMessage":"db: Update %s: clear lease: %w","messagePattern":"db: Update (.+?): clear lease: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/issue.go","lineNumber":287,"sourceCode":"\n\targs = append(args, id)\n\n\t//nolint:gosec // G201: table is one of two hardcoded constants\n\tq := fmt.Sprintf(\"UPDATE %s SET %s WHERE id = ?\", table, strings.Join(setClauses, \", \"))\n\tres, err := r.runner.ExecContext(ctx, q, args...)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"db: Update %s: %w\", id, err)\n\t}\n\trows, err := res.RowsAffected()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"db: Update %s: rows affected: %w\", id, err)\n\t}\n\tif rows == 0 {\n\t\treturn fmt.Errorf(\"db: Update %s: %w\", id, sql.ErrNoRows)\n\t}\n\tif clearLease && !opts.UseWispsTable {\n\t\tif err := issueops.DeleteLeaseInTx(ctx, r.runner, id); err != nil {\n\t\t\treturn fmt.Errorf(\"db: Update %s: clear lease: %w\", id, err)\n\t\t}\n\t}\n\n\t// Event-type parity: embedded records EventClosed / EventReopened /\n\t// EventStatusChanged for status transitions (issueops.DetermineEventType),\n\t// EventUpdated otherwise.\n\teventType := types.EventUpdated\n\tif statusChanging {\n\t\teventType = issueops.DetermineEventType(oldIssue, updates)\n\t}\n\tif err := r.events.Record(ctx, domain.Event{\n\t\tIssueID: id,\n\t\tType:    eventType,\n\t\tActor:   actor,\n\t}, domain.RecordEventOpts{UseWispsTable: opts.UseWispsTable}); err != nil {\n\t\treturn err\n\t}\n","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/issue.go#L269-L305","documentation":"Wrapped failure from the lease-cleanup step: after a successful UPDATE, if ManageLeaseOnUpdate determined the lease must be cleared (and the wisps table is not in use), Update runs issueops.DeleteLeaseInTx. This error means that delete failed. The issue row itself is already updated; only the lease row remains uncleared, so the unit of work aborts with an inconsistent in-transaction state (the surrounding transaction should roll back both).","triggerScenarios":"Calling Update whose updates clear the lease/ownership (e.g. status or assignee change per ManageLeaseOnUpdate) where DeleteLeaseInTx's DELETE fails — connectivity loss, lock contention on the lease row, or driver error inside the same transaction.","commonSituations":"Concurrent claim/update racing on the lease row; server hiccup mid-transaction; foreign-key or permission problems on the lease table.","solutions":["Check the wrapped inner error from DeleteLeaseInTx for the driver-level cause.","Retry the whole unit of work; the transactional wrapper ensures the prior UPDATE is not partially committed.","Inspect lease-row contention (concurrent Claim) and serialize conflicting operations.","Verify lease table schema/permissions if the delete consistently fails."],"exampleFix":"// before: ignoring partial failure\nerr := repo.Update(ctx, id, updates, actor, opts)\n// after: redo the unit of work so lease cleanup re-runs\nif err := repo.Update(ctx, id, updates, actor, opts); err != nil && strings.Contains(err.Error(), \"clear lease\") {\n    return redoUnitOfWork(ctx, id, updates)\n}","handlingStrategy":"retry","validationCode":"// avoid forcing lease clear outside the wisps path unexpectedly\nif clearLeaseIntended && opts.UseWispsTable { /* lease clearing is skipped — account for it */ }","typeGuard":null,"tryCatchPattern":"if err := repo.Update(ctx, id, updates, actor, opts); err != nil && strings.Contains(err.Error(), \"clear lease\") {\n    // transaction rolled back: redo the whole unit of work on a fresh session\n    return redoUnitOfWork(freshCtx, id, updates)\n}","preventionTips":["Serialize claim/update operations to avoid lease-row contention","Always redo the full unit of work — the prior UPDATE rolls back with the transaction","Keep lease-table schema and permissions correct","Monitor for repeated clear-lease failures as a sign of server or contention issues"],"tags":["database","lease","transaction"],"backgroundTag":"lease-cleanup-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}