gastownhall/beads · error
get dependents: %w
Error message
get dependents: %w
What it means
DeleteIssuesInTx wraps a failure from ExternalDependentsBySourceInTx — the single dependency-plane scan used both to guard non-forced deletes and to compute orphans for forced ones. The guard returns a DependentsOutsideRequestError when a regular issue would be orphaned; this wrap only fires when that scan itself fails.
Source
Thrown at internal/storage/issueops/delete.go:163
}
var orphaned []string
if !cascade {
// The guard here is the STORAGE SEAM's, and it stays durable-only: the
// server-backed store peels wisps off before it ever reaches this
// function (dolt/issues.go DeleteIssues), so widening it would make the
// embedded store refuse where the server-backed one cannot. The ROLE's
// guard, which does cover both planes, is in DeleteInTx.
idSet := make(map[string]bool, len(ids))
for _, id := range ids {
idSet[id] = true
}
// One scan of the dependency planes answers both modes: the guard needs
// to know WHICH id is blocked, and the forced path needs the union of
// what it orphans.
external, err := ExternalDependentsBySourceInTx(ctx, tx, set.RegularIDs, idSet)
if err != nil {
return nil, fmt.Errorf("get dependents: %w", err)
}
if !force {
for _, id := range set.RegularIDs {
if deps := external[id]; len(deps) > 0 {
return &types.DeleteIssuesResult{OrphanedIssues: deps},
&publicops.DependentsOutsideRequestError{IssueID: id, Dependents: deps}
}
}
} else {
orphans := make(map[string]bool)
for _, deps := range external {
for _, id := range deps {
orphans[id] = true
}
}
orphaned = workapi.SortedDeleteIDs(orphans)
}
}View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped SQL error for the concrete cause.
- Retry the bulk delete in a fresh transaction; batch the ids to shrink the scan.
- Increase the context timeout proportional to batch size.
- If lock-wait appears, pause concurrent writers (compact, sweep) during the delete.
Defensive patterns
Strategy: retry
Validate before calling
// keep batches small enough that the dependents scan stays fast
if len(ids) > 500 { ids = ids[:500] /* process in chunks */ } Try / catch
res, err := storage.DeleteIssues(ctx, db, ids, cascade, force, dryRun)
if err != nil {
if isTransientDBError(err) { /* fresh tx retry */ }
return err
}
// note: res.OrphanedIssues + DependentsOutsideRequestError are the expected
// guard outcome, distinct from this wrap. Prevention
- Batch bulk deletes; the external-dependents scan scales with id count.
- Use dryRun first to see the intended deletion set without the guard scan failing late.
- Avoid concurrent sweeps/deletes on the same ids.
When it happens
Trigger: Bulk delete (bd delete with multiple ids, also invoked from SweepInTx) when the external-dependents query errors: context timeout scanning many regular ids, connection loss, or SQL failure on the dependency tables.
Common situations: Deleting a large batch where the dependents scan times out; concurrent dependency writes causing lock waits; degraded Dolt server under memory pressure during the join scan.
Related errors
- count dependencies: %w
- iter dependents: query: %w
- getting issue %s: %w
- db: ChildCounterSQLRepository.NextChildID: probe parent tabl
- db: ChildCounterSQLRepository.NextChildID: read counter for
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/14475a58d6f58910.
Report an issue: GitHub.