{"record":{"id":"99be977608e7dc1d","repo":"gastownhall/beads","slug":"reopen-s-reload-w","errorCode":null,"errorMessage":"reopen %s: reload: %w","messagePattern":"reopen (.+?): reload: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/issue.go","lineNumber":1723,"sourceCode":"\nfunc (u *issueUseCaseImpl) ReopenWisp(ctx context.Context, id string, params ReopenIssueParams, actor string) (ReopenIssueResult, error) {\n\treturn u.reopen(ctx, id, params, actor, true)\n}\n\nfunc (u *issueUseCaseImpl) reopen(ctx context.Context, id string, params ReopenIssueParams, actor string, useWisp bool) (ReopenIssueResult, error) {\n\tif id == \"\" {\n\t\treturn ReopenIssueResult{}, fmt.Errorf(\"reopen: id must not be empty\")\n\t}\n\tif actor == \"\" {\n\t\treturn ReopenIssueResult{}, fmt.Errorf(\"reopen: actor must not be empty\")\n\t}\n\trow, err := u.issueRepo.Reopen(ctx, id, ReopenRowParams{Reason: params.Reason}, actor, IssueTableOpts{UseWispsTable: useWisp})\n\tif err != nil {\n\t\treturn ReopenIssueResult{}, fmt.Errorf(\"reopen %s: %w\", id, err)\n\t}\n\tissue, err := u.issueRepo.Get(ctx, id, IssueTableOpts{UseWispsTable: row.IsWisp})\n\tif err != nil {\n\t\treturn ReopenIssueResult{}, fmt.Errorf(\"reopen %s: reload: %w\", id, err)\n\t}\n\treturn ReopenIssueResult{\n\t\tIssue:    issue,\n\t\tReopened: row.Updated,\n\t}, nil\n}\n\nfunc (u *issueUseCaseImpl) ClaimIssueIfOpen(ctx context.Context, id, actor string) (ClaimResult, error) {\n\treturn u.claim(ctx, id, actor, false)\n}\n\nfunc (u *issueUseCaseImpl) ClaimWispIfOpen(ctx context.Context, id, actor string) (ClaimResult, error) {\n\treturn u.claim(ctx, id, actor, true)\n}\n\nfunc (u *issueUseCaseImpl) CountOpenChildren(ctx context.Context, id string) (int, error) {\n\treturn u.countOpenChildren(ctx, id, false)\n}","sourceCodeStart":1705,"sourceCodeEnd":1741,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/issue.go#L1705-L1741","documentation":"Reload-failure variant for reopen: issueRepo.Reopen succeeded but the subsequent issueRepo.Get to return the freshly reopened issue failed. The 'reopen <id>: reload:' wrapper distinguishes the failed read-back from a failed reopen.","triggerScenarios":"ReopenIssue flow where Reopen commits and u.issueRepo.Get(ctx, id, IssueTableOpts{UseWispsTable: row.IsWisp}) then fails — concurrent delete/move of the row, storage read error, or wisp-table mismatch between write and read.","commonSituations":"Wisp compaction moving/removing the row between the two calls; transient DB read failure; concurrent agent deleting the issue after it was reopened; replica lag.","solutions":["Retry; the reopen is committed and effectively idempotent.","If the cause is not-found, search/list to find which table now holds the row.","Check storage health and driver errors in the wrapped cause.","Skip the reload and treat Reopened: true as authoritative if eventual consistency suffices."],"exampleFix":"// before\nres, err := usecase.ReopenIssue(ctx, id, params, actor)\n// after\nif err != nil && strings.Contains(err.Error(), \"reload\") {\n    issue, ferr := usecase.GetIssue(ctx, id) // separate re-fetch\n    _ = issue; _ = ferr\n}","handlingStrategy":"try-catch","validationCode":"if _, err := usecase.GetIssue(ctx, id); err != nil {\n    return fmt.Errorf(\"issue %s unreadable before reopen\", id)\n}","typeGuard":"func isReloadErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \": reload: \")\n}","tryCatchPattern":"res, err := usecase.ReopenIssue(ctx, id, params, actor)\nif isReloadErr(err) {\n    issue, ferr := usecase.GetIssue(ctx, id)\n    if ferr != nil {\n        log.Warnf(\"reload after reopen failed: %v\", ferr)\n    }\n    return nil // reopen committed\n}","preventionTips":["Avoid concurrent deletion during reopen workflows.","Retry the reload path once on transient errors.","Check wisp table state if the reopened row is a wisp.","Inspect the wrapped cause for the definitive read failure."],"tags":["storage","reopen-issue","reload","wrapped-error"],"backgroundTag":"post-write-reload-failure","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}