gastownhall/beads · error

CountOpenChildren %s: %w

Error message

CountOpenChildren %s: %w

What it means

This error is returned by CountOpenChildren in the issue use-case layer when the underlying repository call ListWithIssueMetadata fails while counting non-closed children of an issue. The issue ID and the wrapped repository error are embedded so the caller can see exactly which parent issue's child count could not be computed. It is a pass-through wrapper: the root cause (storage/query failure) is preserved via %w.

Source

Thrown at internal/storage/domain/issue.go:1757

func (u *issueUseCaseImpl) CountOpenChildren(ctx context.Context, id string) (int, error) {
	return u.countOpenChildren(ctx, id, false)
}

func (u *issueUseCaseImpl) CountOpenWispChildren(ctx context.Context, id string) (int, error) {
	return u.countOpenChildren(ctx, id, true)
}

func (u *issueUseCaseImpl) countOpenChildren(ctx context.Context, id string, useWisp bool) (int, error) {
	if id == "" {
		return 0, fmt.Errorf("CountOpenChildren: id must not be empty")
	}
	children, err := u.depRepo.ListWithIssueMetadata(ctx, id, DepListOpts{
		Types:         []types.DependencyType{types.DepParentChild},
		Direction:     DepDirectionIn,
		UseWispsTable: useWisp,
	})
	if err != nil {
		return 0, fmt.Errorf("CountOpenChildren %s: %w", id, err)
	}
	open := 0
	for _, child := range children {
		if child.Status != types.StatusClosed {
			open++
		}
	}
	return open, nil
}

func (u *issueUseCaseImpl) GetNewlyUnblockedByClose(ctx context.Context, closedID string) ([]*types.Issue, error) {
	return u.getNewlyUnblockedByClose(ctx, closedID)
}

func (u *issueUseCaseImpl) GetNewlyUnblockedByCloseWisp(ctx context.Context, closedID string) ([]*types.Issue, error) {
	return u.getNewlyUnblockedByClose(ctx, closedID)
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped error (%w chain) printed after 'CountOpenChildren <id>:' to find the root cause
  2. Verify the issue ID exists (e.g. bd show <id>) before counting children
  3. Check database connectivity and re-run; transient storage failures can be retried
  4. If using the wisp path, confirm the wisps table exists and is migrated

Example fix

// before
n, err := uc.CountOpenChildren(ctx, id, false)
if err != nil { return err }
// after
n, err := uc.CountOpenChildren(ctx, id, false)
if err != nil {
    var nf *types.ErrNotFound
    if errors.As(err, &nf) { return nil } // treat missing parent as zero children
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

if id == "" {
    return 0, fmt.Errorf("cannot count children: empty issue id")
}

Type guard

func hasID(id string) bool { return strings.TrimSpace(id) != "" }

Try / catch

open, err := uc.CountOpenChildren(ctx, id, useWisp)
if err != nil {
    log.Warnf("child count unavailable for %s: %v", id, err)
    return -1 // or skip gracefully
}

Prevention

When it happens

Trigger: Calling CountOpenChildren (directly or via CountOpenChildrenWisp) when u.depRepo.ListWithIssueMetadata(ctx, id, DepListOpts{Types:[DepParentChild], Direction:In, UseWispsTable:useWisp}) returns a non-nil error, e.g. the issue ID does not exist, the database is unreachable, or the dependency table query fails.

Common situations: Querying a deleted/renamed issue ID in a script that counts open subtasks; Dolt database connection drops mid-query; schema mismatch when the wisps table flag (useWisp) selects a table that is missing or migrated.

Related errors


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