{"record":{"id":"6b660514fc78128f","repo":"gastownhall/beads","slug":"check-remaining-blocker-status-w","errorCode":null,"errorMessage":"check remaining blocker status: %w","messagePattern":"check remaining blocker status: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/dependency_queries.go","lineNumber":874,"sourceCode":"\t\t\t\t\treturn nil, fmt.Errorf(\"scan remaining blocker: %w\", err)\n\t\t\t\t}\n\t\t\t\tremainingByCandidate[candidateID] = append(remainingByCandidate[candidateID], blockerID)\n\t\t\t\tremainingBlockerSet[blockerID] = struct{}{}\n\t\t\t}\n\t\t\t_ = depRows.Close()\n\t\t\tif err := depRows.Err(); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"remaining blocker rows from %s: %w\", depTable, err)\n\t\t\t}\n\t\t}\n\n\t\tremainingBlockerIDs := make([]string, 0, len(remainingBlockerSet))\n\t\tfor blockerID := range remainingBlockerSet {\n\t\t\tremainingBlockerIDs = append(remainingBlockerIDs, blockerID)\n\t\t}\n\t\tsort.Strings(remainingBlockerIDs)\n\t\tstatusByID, err := loadStatusByIDInTx(ctx, tx, remainingBlockerIDs)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"check remaining blocker status: %w\", err)\n\t\t}\n\t\tfor candidateID, blockerIDs := range remainingByCandidate {\n\t\t\tfor _, blockerID := range blockerIDs {\n\t\t\t\tstatus, ok := statusByID[blockerID]\n\t\t\t\tif ok && status != types.StatusClosed && status != types.StatusPinned {\n\t\t\t\t\tstillBlocked[candidateID] = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tvar unblocked []*types.Issue\n\tfor _, id := range candidateIDs {\n\t\tif stillBlocked[id] {\n\t\t\tcontinue\n\t\t}\n\t\tissue, err := GetIssueInTx(ctx, tx, id)","sourceCodeStart":856,"sourceCodeEnd":892,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/dependency_queries.go#L856-L892","documentation":"Wraps a failure from loadStatusByIDInTx while fetching statuses of remaining blocker issues inside GetNewlyUnblockedByCloseInTx. The dependency edges were read fine, but resolving whether each blocker is still open/closed/pinned failed, so the function cannot safely decide which candidates became unblocked.","triggerScenarios":"The batch status lookup for remainingBlockerIDs fails — e.g. the issues table query inside loadStatusByIDInTx errors due to schema problems, lock contention, or driver errors.","commonSituations":"Issues table missing or migrated to an unexpected shape; transaction deadlock/lock timeout with concurrent writers; embedded DB corruption.","solutions":["Inspect the wrapped error from loadStatusByIDInTx for the root cause","Verify the issues table exists with the expected id/status columns","Resolve lock contention (retry the transaction) if the error is a deadlock/timeout","Run storage integrity checks/repairs if corruption is indicated"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// ensure issues table is healthy\n_ = db.QueryRow(\"SELECT COUNT(*) FROM issues WHERE status != ''\").Scan(&n)","typeGuard":null,"tryCatchPattern":"if err := tx.CloseIssue(ctx, id); err != nil {\n\tif strings.Contains(err.Error(), \"check remaining blocker status\") {\n\t\t// inspect issues-table health, then retry\n\t}\n\treturn err\n}","preventionTips":["Keep the issues table schema current via migrations","Limit concurrent writers to reduce lock contention","Run bd doctor periodically on embedded databases"],"tags":["go","sql","storage","status-lookup"],"backgroundTag":"sql-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}