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

  1. Fix the underlying DB error reported by the wrapped cause, then retry the delete
  2. 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
  3. Verify DB privileges for the dependency tables
  4. 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

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


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/a12145c06f81302b. Report an issue: GitHub.