gastownhall/beads · error
reparent: childID must not be empty
Error message
reparent: childID must not be empty
What it means
Guard error from reparent (backing Reparent and ReparentWisp): childID is the empty string. Reparenting requires knowing which child to move; the use case refuses before any repository work. A newParentID of "" is not caught here explicitly (only the childID==newParentID equality check follows), so the empty child is the guarded precondition.
Source
Thrown at internal/storage/domain/dependency.go:382
return fmt.Errorf("remove dep: sourceID and dependsOnID must not be empty")
}
if _, err := u.depRepo.Delete(ctx, sourceID, dependsOnID, actor, DepInsertOpts{UseWispsTable: useWisp, EmitEvent: true}); err != nil {
return fmt.Errorf("remove dep %s -> %s: %w", sourceID, dependsOnID, err)
}
return nil
}
func (u *dependencyUseCaseImpl) Reparent(ctx context.Context, childID, newParentID, actor string) error {
return u.reparent(ctx, childID, newParentID, actor, false)
}
func (u *dependencyUseCaseImpl) ReparentWisp(ctx context.Context, childWispID, newParentID, actor string) error {
return u.reparent(ctx, childWispID, newParentID, actor, true)
}
func (u *dependencyUseCaseImpl) reparent(ctx context.Context, childID, newParentID, actor string, useWisp bool) error {
if childID == "" {
return fmt.Errorf("reparent: childID must not be empty")
}
if childID == newParentID {
return fmt.Errorf("reparent: %s cannot be its own parent", childID)
}
opts := DepInsertOpts{UseWispsTable: useWisp}
res, err := u.depRepo.ListByIssueIDs(ctx, []string{childID}, DepListOpts{
Types: []types.DependencyType{types.DepParentChild},
Direction: DepDirectionOut,
UseWispsTable: useWisp,
})
if err != nil {
return fmt.Errorf("reparent: list current parent: %w", err)
}
// A child can carry MORE THAN ONE parent-child edge — Create accepts
// CreateRequest.ParentID and an explicit parent-child entry in
// Dependencies in the same request — so this is a set replacement, not aView on GitHub (pinned to 71377f2769)
Solutions
- Check childID for emptiness before calling Reparent / ReparentWisp.
- Resolve the child issue via lookup first and abort with a clear message if it cannot be found.
- Fix the upstream parse/config that produced the blank ID.
- In batch reparent jobs, skip or log entries with empty IDs instead of passing them through.
Example fix
// before
err := uc.Reparent(ctx, childID, newParentID, actor)
// after
if childID == "" {
return fmt.Errorf("reparent skipped: child id missing")
}
err := uc.Reparent(ctx, childID, newParentID, actor) Defensive patterns
Strategy: validation
Validate before calling
func readyToReparent(childID, newParentID string) error {
if childID == "" {
return fmt.Errorf("childID must not be empty")
}
if childID == newParentID {
return fmt.Errorf("child cannot be its own parent")
}
return nil
}
if err := readyToReparent(childID, newParentID); err != nil {
return err
}
err := uc.Reparent(ctx, childID, newParentID, actor) Type guard
func validChildID(id string) bool { return id != "" } Try / catch
if !validChildID(childID) {
return fmt.Errorf("reparent skipped: missing child id")
}
if err := uc.Reparent(ctx, childID, newParentID, actor); err != nil {
return fmt.Errorf("reparent failed: %w", err)
} Prevention
- Resolve and verify the child issue exists before reparent calls
- Skip/log empty IDs in batch reparent jobs
- Fail fast on failed upstream lookups instead of forwarding empty IDs
- Validate CLI/config inputs at parse time
When it happens
Trigger: Reparent(ctx, "", parentID, actor) or ReparentWisp with an empty child ID — usually a failed upstream lookup, a blank CLI argument, or a struct field left at its zero value before the call.
Common situations: Scripts re-parenting issues from a list where one ID failed to resolve; YAML/JSON config with a missing child key; passing a *types.Issue whose ID was never persisted.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- remove dep: sourceID and dependsOnID must not be empty
- reparent: %s cannot be its own parent
- DeleteIssue: id must not be empty
- DeleteWisp: id must not be empty
- no store is open for this workspace
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/afd017b3a47d7c53.
Report an issue: GitHub.