gastownhall/beads · error

CountOpenChildren: id must not be empty

Error message

CountOpenChildren: id must not be empty

What it means

A guard error thrown by countOpenChildren() (backing CountOpenChildren and CountOpenWispChildren) when the issue ID is empty. The method counts open child issues via dependency edges inbound of type parent-child, and an empty ID can never match any parent, so the library fails fast.

Source

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

func (u *issueUseCaseImpl) ClaimIssueIfOpen(ctx context.Context, id, actor string) (ClaimResult, error) {
	return u.claim(ctx, id, actor, false)
}

func (u *issueUseCaseImpl) ClaimWispIfOpen(ctx context.Context, id, actor string) (ClaimResult, error) {
	return u.claim(ctx, id, actor, true)
}

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
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Provide a valid parent issue ID before counting children.
  2. Validate id != "" at the call site or skip the count for blank IDs in batch loops.
  3. Fix the upstream lookup that produced the empty ID (failed Get, empty field).

Example fix

// before
count, err := usecase.CountOpenChildren(ctx, id) // id == ""
// after
if id == "" { return 0, fmt.Errorf("parent id required") }
count, err := usecase.CountOpenChildren(ctx, id)
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(id) == "" {
    return 0, fmt.Errorf("count children: parent id must not be empty")
}

Type guard

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

Try / catch

n, err := usecase.CountOpenChildren(ctx, id)
if err != nil {
    if strings.Contains(err.Error(), "id must not be empty") {
        return 0, fmt.Errorf("skipping child count: no parent ID")
    }
    return err
}

Prevention

When it happens

Trigger: Calling CountOpenChildren / CountOpenWispChildren with id="" — e.g. an empty parent ID passed from close-time checks, or a caller computing dependencies for an unresolved/blank issue reference.

Common situations: Close workflows computing 'open children' warnings for an issue whose ID was lost upstream; batch scripts iterating entries with blank IDs; automation passing an empty variable after a failed lookup.

Related errors


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