gastownhall/beads · error
previewDelete: cascade expansion: %w
Error message
previewDelete: cascade expansion: %w
What it means
This error wraps a failure from issueRepo.FindAllDependents in previewDelete, which transitively expands the delete set to all dependents (the cascade). Without this expansion the preview could not show which issues disappear when cascade delete is enabled.
Source
Thrown at internal/storage/domain/issue_delete.go:321
depRes, err := u.depRepo.ListByIssueIDs(ctx, ids, DepListOpts{Direction: DepDirectionOut})
if err != nil {
return preview, fmt.Errorf("previewDelete: list deps: %w", err)
}
for id, deps := range depRes.Outgoing {
preview.DepRecords[id] = deps
}
wispDepRes, err := u.depRepo.ListByIssueIDs(ctx, ids, DepListOpts{Direction: DepDirectionOut, UseWispsTable: true})
if err != nil && !dberrors.IsTableNotExist(err) {
return preview, fmt.Errorf("previewDelete: list wisp deps: %w", err)
}
for id, deps := range wispDepRes.Outgoing {
preview.DepRecords[id] = append(preview.DepRecords[id], deps...)
}
allIDs, err := u.issueRepo.FindAllDependents(ctx, ids)
if err != nil {
return preview, fmt.Errorf("previewDelete: cascade expansion: %w", err)
}
deletedSet := make(map[string]bool, len(allIDs))
for _, id := range allIDs {
deletedSet[id] = true
}
connected, _, err := u.collectConnectedIssues(ctx, allIDs, deletedSet)
if err != nil {
return preview, err
}
preview.ConnectedIssues = connected
return preview, nil
}
func (u *issueUseCaseImpl) collectConnectedIssues(
ctx context.Context, allIDs []string, deletedSet map[string]bool,
) (map[string]*types.Issue, map[string]bool, error) {
out := map[string]*types.Issue{}
isWisp := map[string]bool{}View on GitHub (pinned to 71377f2769)
Solutions
- Increase the query/statement timeout for the cascade lookup.
- Inspect the wrapped driver error and fix connectivity.
- Preview smaller id subsets to shrink the cascade.
- Retry — the preview is read-only and safe to re-run.
Defensive patterns
Strategy: retry
Validate before calling
// Bound the cascade before previewing: preview fewer ids at a time.
if len(ids) > maxBatch {
return fmt.Errorf("preview batch too large (%d > %d); split it", len(ids), maxBatch)
} Type guard
var dbErr *dberrors.DBError
if errors.As(err, &dbErr) {
// inspect timeout vs connectivity codes
} Try / catch
preview, err := uc.PreviewDelete(ctx, ids)
if err != nil && strings.Contains(err.Error(), "previewDelete: cascade expansion") {
// often a timeout on deep graphs — retry with longer timeout or smaller batch
return retryWithLongerTimeout(func() error { _, e := uc.PreviewDelete(ctx, ids); return e })
} Prevention
- Increase statement timeouts for deep dependency graphs
- Preview in smaller id batches
- Watch for runaway dependency chains in your issue graph
- Retry — cascade expansion is read-only
When it happens
Trigger: PreviewDelete/PreviewDeleteWisp when the recursive dependent-lookup query fails: deep dependency graphs causing expensive/recursive queries, DB timeout, or connection loss.
Common situations: Very deep or cyclic-heavy dependency graphs making cascade expansion slow enough to hit statement timeouts; Dolt connection drops during long recursive queries.
Related errors
- previewDelete: load issues: %w
- previewDelete: load wisps: %w
- previewDelete: list deps: %w
- previewDelete: list wisp deps: %w
- no store is open for this workspace
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/9de9ceea54bd7a92.
Report an issue: GitHub.