gastownhall/beads · error

inherit labels: list parent %s: %w

Error message

inherit labels: list parent %s: %w

What it means

This error wraps a failure from labelRepo.List when reading the parent issue's existing labels during inheritance (internal/storage/domain/label.go). The prefix includes the parent ID so the failing parent is identifiable. The original repository error is preserved with %w.

Source

Thrown at internal/storage/domain/label.go:238

func (u *labelUseCaseImpl) InheritFromParent(ctx context.Context, childID, parentID, actor string, skipExisting []string) ([]string, error) {
	return u.inherit(ctx, childID, parentID, actor, skipExisting, false)
}

func (u *labelUseCaseImpl) InheritFromWispParent(ctx context.Context, childWispID, parentWispID, actor string, skipExisting []string) ([]string, error) {
	return u.inherit(ctx, childWispID, parentWispID, actor, skipExisting, true)
}

func (u *labelUseCaseImpl) inherit(ctx context.Context, childID, parentID, actor string, skipExisting []string, useWisp bool) ([]string, error) {
	if childID == "" {
		return nil, fmt.Errorf("inherit labels: childID must not be empty")
	}
	if parentID == "" {
		return nil, fmt.Errorf("inherit labels: parentID must not be empty")
	}
	parentLabels, err := u.labelRepo.List(ctx, parentID, LabelOpts{UseWispsTable: useWisp})
	if err != nil {
		return nil, fmt.Errorf("inherit labels: list parent %s: %w", parentID, err)
	}
	if len(parentLabels) == 0 {
		return nil, nil
	}
	skip := make(map[string]bool, len(skipExisting))
	for _, s := range skipExisting {
		skip[s] = true
	}
	var inherited []string
	for _, label := range parentLabels {
		if skip[label] {
			continue
		}
		if err := u.labelRepo.Insert(ctx, childID, label, actor, LabelOpts{UseWispsTable: useWisp}); err != nil {
			return inherited, fmt.Errorf("inherit labels: insert %s on %s: %w", label, childID, err)
		}
		inherited = append(inherited, label)
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped cause (errors.Unwrap) to identify the repository-level failure.
  2. Verify the parent issue/wisp actually exists in the database (bd show <parentID>).
  3. Check database availability/locks and close competing bd processes.
  4. Retry with a fresh context if ctx.Err() indicates cancellation or timeout.

Example fix

// before
_, err := uc.InheritFromParent(ctx, childID, parentID, actor, nil)
if err != nil { log.Fatal(err) }
// after
_, err := uc.InheritFromParent(ctx, childID, parentID, actor, nil)
if err != nil {
    log.Printf("inherit from %s failed: %v", parentID, errors.Unwrap(err))
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify parent exists first
labels, err := uc.GetLabels(ctx, parentID)
if err != nil { return fmt.Errorf("parent %s unreadable: %w", parentID, err) }

Try / catch

_, err := uc.InheritFromParent(ctx, childID, parentID, actor, nil)
if err != nil {
    if ctx.Err() != nil { return ctx.Err() }
    log.Printf("parent %s label list failed: %v", parentID, errors.Unwrap(err))
    return err
}

Prevention

When it happens

Trigger: Calling InheritFromParent or InheritFromWispParent when labelRepo.List(parentID, LabelOpts{UseWispsTable: ...}) fails: database locked/unavailable, parent issue row missing in the labels table source, context canceled, or wisps-table routing to a nonexistent table.

Common situations: Reading from a partially-migrated Dolt database; concurrent bd processes holding the DB lock; querying a parent wisp that was deleted while inheritance was in flight.

Related errors


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