{"record":{"id":"58588e127a7201d6","repo":"gastownhall/beads","slug":"journal-dependency-removals-for-source-repo-delete","errorCode":null,"errorMessage":"journal dependency removals for source-repo delete: %w","messagePattern":"journal dependency removals for source-repo delete: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/bulk_ops.go","lineNumber":210,"sourceCode":"\t\treturn 0, nil\n\t}\n\n\taffectedIssues, affectedWisps, aerr := AffectedByDeletionInTx(ctx, tx, issueIDs, nil)\n\tif aerr != nil {\n\t\treturn 0, fmt.Errorf(\"affected by source-repo delete: %w\", aerr)\n\t}\n\n\t// Deleted issues hold no leases: clear them while the id set is still\n\t// joinable (before the issues rows go away).\n\tif _, err := tx.ExecContext(ctx,\n\t\t`DELETE FROM leases WHERE issue_id IN (SELECT id FROM issues WHERE source_repo = ?)`, sourceRepo); err != nil {\n\t\treturn 0, fmt.Errorf(\"delete leases: %w\", err)\n\t}\n\n\t// Edges are journaled before the rows go, while their source snapshots can\n\t// still be read.\n\tif err := RecordDependencyRemovalsForIssuesInTx(ctx, tx, issueIDs); err != nil {\n\t\treturn 0, fmt.Errorf(\"journal dependency removals for source-repo delete: %w\", err)\n\t}\n\n\tresult, err := tx.ExecContext(ctx, `DELETE FROM issues WHERE source_repo = ?`, sourceRepo)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"delete issues: %w\", err)\n\t}\n\n\trowsAffected, err := result.RowsAffected()\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"rows affected: %w\", err)\n\t}\n\n\t// Journal each deleted issue in the same transaction. issueIDs is the exact\n\t// set removed by the DELETE above (both were scoped to source_repo), so\n\t// there are no phantom records here. The source-repo bulk delete plumbing\n\t// carries no actor, so the rows record none.\n\tfor _, id := range issueIDs {\n\t\tif err := RecordDeleteInTx(ctx, tx, id, \"\"); err != nil {","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/bulk_ops.go#L192-L228","documentation":"Before removing issue rows, dependency edges are journaled via RecordDependencyRemovalsForIssuesInTx; failure is wrapped as \"journal dependency removals for source-repo delete: %w\". This preserves the edge data for sync before deletion.","triggerScenarios":"RecordDependencyRemovalsForIssuesInTx errors while reading or inserting dependency-removal records: failing SELECT on dependencies, INSERT into the journal/compaction table fails, or context canceled mid-way.","commonSituations":"Journal table missing or full (disk quota); schema drift between journal writer and reader; timeout while journaling a repo with thousands of edges.","solutions":["Inspect the inner error returned by RecordDependencyRemovalsForIssuesInTx","Verify the journal/dependencies tables exist and are writable","Free disk space / raise quota if inserts fail from a full disk","Retry with a longer context for large edge sets"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// confirm the journal table is present and writable\n_, err := db.Exec(\"SELECT 1 FROM deletions LIMIT 1\") // or the relevant journal table","typeGuard":"var noTableErr interface{ Error() string }\n_ = errors.As(err, &noTableErr) // \"no such table\" indicates schema drift","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"journal dependency removals\") {\n    // journal write failed: verify disk space/schema, retry transaction\n    return fmt.Errorf(\"cannot journal before delete: %w\", err)\n}","preventionTips":["Keep disk quota headroom for journal writes","Run migrations before bulk deletes so journal tables exist","Never skip journaling; without it sync cannot reproduce the delete"],"tags":["database","journal","sync"],"backgroundTag":"sql-insert-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}