gastownhall/beads · error

hydrate neighbors (issues): %w

Error message

hydrate neighbors (issues): %w

What it means

This error wraps a failure from issueRepo.GetByIDs while hydrating the neighbor issues discovered during a connected-delete traversal. collectConnectedIssues first collects dependency edges, then bulk-loads the actual issue rows for the neighbor IDs from the durable `issues` table. If that bulk fetch fails (DB error, corruption, context cancel), the delete/preview operation aborts with this wrapped message.

Source

Thrown at internal/storage/domain/issue_delete.go:381

			}
		}
	}
	accumulate(issueRes.Outgoing)
	accumulate(issueRes.Incoming)
	accumulate(wispRes.Outgoing)
	accumulate(wispRes.Incoming)

	if len(neighbors) == 0 {
		return out, isWisp, nil
	}
	ids := make([]string, 0, len(neighbors))
	for id := range neighbors {
		ids = append(ids, id)
	}

	fromIssues, err := u.issueRepo.GetByIDs(ctx, ids, IssueTableOpts{})
	if err != nil {
		return nil, nil, fmt.Errorf("hydrate neighbors (issues): %w", err)
	}
	for _, iss := range fromIssues {
		out[iss.ID] = iss
	}
	fromWisps, err := u.issueRepo.GetByIDs(ctx, ids, IssueTableOpts{UseWispsTable: true})
	if err != nil && !dberrors.IsTableNotExist(err) {
		return nil, nil, fmt.Errorf("hydrate neighbors (wisps): %w", err)
	}
	for _, iss := range fromWisps {
		out[iss.ID] = iss
		isWisp[iss.ID] = true
	}
	return out, isWisp, nil
}

func (u *issueUseCaseImpl) rewriteTextReferences(
	ctx context.Context, deletedIDs []string,
	connected map[string]*types.Issue, isWisp map[string]bool, actor string,

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the wrapped cause (%w) for the underlying driver/SQL error and fix that first (connection, lock, corruption).
  2. Verify the database is reachable and not locked by another process (e.g. another bd session holding a write lock).
  3. Retry the delete/preview with a fresh, uncanceled context; ensure no caller cancels ctx mid-operation.
  4. If corruption is suspected, run bd doctor / repair the store, then retry.
  5. Confirm the neighbor IDs collected are valid (no empty/garbage IDs) — malformed IDs can surface as query errors.

Example fix

// before: cancelable request ctx flows into a long delete
deleter.DeleteMany(ctx, ids)

// after: use an operation-scoped context with timeout for the delete
opCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
deleteErr := deleter.DeleteMany(opCtx, ids)
Defensive patterns

Strategy: try-catch

Validate before calling

// before deleting, confirm the DB is reachable and ids are non-empty
if len(ids) == 0 { return errors.New("no ids to delete") }
if err := db.PingContext(ctx); err != nil { return fmt.Errorf("store unreachable: %w", err) }

Type guard

func isHydrateNeighborsErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "hydrate neighbors (issues)")
}

Try / catch

err := usecase.DeleteMany(ctx, ids)
if err != nil {
    var wrapped interface{ Unwrap() error }
    if strings.Contains(err.Error(), "hydrate neighbors (issues)") {
        // retry after checking connectivity; underlying cause via errors.Unwrap
    }
    return err
}

Prevention

When it happens

Trigger: Calling deleteMany or previewDelete when the batch has dependency neighbors, and the GetByIDs query against the durable issues table fails — e.g. database closed/locked, connection dropped, context canceled mid-query, or a storage driver error.

Common situations: Deleting a batch of issues over an unstable Dolt/embedded DB connection; canceling a long-running bd delete; a corrupted or partially-migrated database where the issues table is unreadable; hitting a driver-level timeout during bulk hydration.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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