gastownhall/beads · error
delete: check dependents: %w
Error message
delete: check dependents: %w
What it means
While collecting external dependents before a delete, one of the per-plane dependency listing queries (incoming edges) failed. Only optional planes with a 'table does not exist' error are skipped; any other failure aborts the delete with this wrapped error, leaving the delete unperformed.
Source
Thrown at internal/storage/uow/deleter.go:218
depUC := uw.DependencyUseCase()
bySource := make(map[string]map[string]bool)
for _, plane := range []struct {
list func(context.Context, []string, domain.DepListFilter) (domain.DepBulkResult, error)
optional bool
}{
{list: depUC.ListByIssueIDs},
// The wisp plane is optional the way every other cross-plane read here
// treats it: a workspace whose schema predates it has no table, and
// that is not a failed guard.
{list: depUC.ListByWispIDs, optional: true},
} {
res, err := plane.list(ctx, ids, domain.DepListFilter{Direction: domain.DepDirectionIn})
if err != nil {
if plane.optional && dberrors.IsTableNotExist(err) {
continue
}
return nil, fmt.Errorf("delete: check dependents: %w", err)
}
for target, edges := range res.Incoming {
for _, edge := range edges {
if edge == nil || idSet[edge.IssueID] {
continue
}
if bySource[target] == nil {
bySource[target] = make(map[string]bool)
}
bySource[target][edge.IssueID] = true
}
}
}
out := make(map[string][]string, len(bySource))
for target, dependents := range bySource {
out[target] = workapi.SortedDeleteIDs(dependents)
}View on GitHub (pinned to 71377f2769)
Solutions
- Fix the underlying DB error reported by the wrapped cause, then retry the delete
- If a plane's table is genuinely gone but the error is not classified as TableNotExist, repair the schema (bd doctor/migrations) so it is detected or recreated
- Verify DB privileges for the dependency tables
- Retry after transient connectivity issues
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check which planes' dep tables exist before deleting
for _, t := range []string{"issue_dependencies", "wisp_dependencies"} {
if !tableExists(ctx, db, t) { /* treat as empty plane */ }
} Type guard
func isDependentCheckFailure(err error) bool {
return err != nil && strings.Contains(err.Error(), "delete: check dependents")
} Try / catch
res, err := deleteInUOW(ctx, req)
if isDependentCheckFailure(err) {
if dberrors.IsTableNotExist(errors.Unwrap(err)) { /* optional plane missing: proceed */ }
return fmt.Errorf("cannot verify dependents; delete aborted: %w", err)
} Prevention
- Keep schema migrations current so optional-plane tables either exist cleanly or are absent
- Check DB privileges on dependency tables before bulk deletes
- Treat this error as abort-with-no-changes and fix the DB before retrying
- Run 'bd doctor' when unsure of schema state
When it happens
Trigger: externalDependentsBySourceInUOW calls plane.list with DepListFilter{Direction: In} for each plane; a non-optional plane's query fails, or an optional plane fails with an error other than IsTableNotExist — DB error, connection loss, permission failure, schema drift.
Common situations: Database degradation during delete (timeout, restart); schema drift where a dependency table exists but is broken (not cleanly 'not exist'); permissions revoked on the dependency tables.
Related errors
- delete: drop deps: %w
- delete: drop wisp deps: %w
- delete: count deps: %w
- delete: check dependents: %w
- loading deps for %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/a12145c06f81302b.
Report an issue: GitHub.