gastownhall/beads · error

create: add dep %s -> %s: %w

Error message

create: add dep %s -> %s: %w

What it means

Wraps a failure from depRepo.Insert while adding a dependency (issue depends on another issue) during issue creation inside the storage domain use case. The underlying insert can fail for schema/constraint reasons (unknown issue ID, FK violation, cycle checks) or storage-layer errors. The wrapper names the dependency edge 'issueID -> dependsOnID' so the failing relationship is identifiable.

Source

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

	}

	for _, spec := range params.Dependencies {
		dep := &types.Dependency{
			IssueID:     issue.ID,
			DependsOnID: spec.TargetID,
			Type:        spec.Type,
			Metadata:    spec.Metadata,
			ThreadID:    spec.ThreadID,
		}
		if spec.SwapDirection {
			dep.IssueID, dep.DependsOnID = dep.DependsOnID, dep.IssueID
		}
		depSourceIsWisp, err := u.isWispID(ctx, dep.IssueID)
		if err != nil {
			return result, fmt.Errorf("create: determine dep source tier for %s: %w", dep.IssueID, err)
		}
		if err := u.depRepo.Insert(ctx, dep, actor, DepInsertOpts{UseWispsTable: depSourceIsWisp}); err != nil {
			return result, fmt.Errorf("create: add dep %s -> %s: %w", dep.IssueID, dep.DependsOnID, err)
		}
		result.PostCreateWrites = true
	}

	if params.WaitsFor != nil {
		// Spawner identity is the depends_on_id; metadata carries the gate.
		dep, err := types.NewWaitsForDependency(issue.ID, params.WaitsFor.SpawnerID, params.WaitsFor.Gate)
		if err != nil {
			return result, fmt.Errorf("create: marshal waits-for meta: %w", err)
		}
		if err := u.depRepo.Insert(ctx, dep, actor, DepInsertOpts{UseWispsTable: useWisp}); err != nil {
			return result, fmt.Errorf("create: add waits-for: %w", err)
		}
		result.PostCreateWrites = true
	}

	return result, nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Verify both dep.IssueID and dep.DependsOnID exist (create referenced issues first, or use graph apply which mints IDs before linking)
  2. Check the wrapped inner error (%w) for the storage-level cause (FK violation, duplicate, connection)
  3. Confirm the correct table tier: wisps deps go to the wisps table via UseWispsTable; a wisp ID routed wrong can fail lookup
  4. Retry transient storage errors; investigate driver/connection if persistent

Example fix

// before: dep references an issue that doesn't exist yet
CreateIssueParams{Issue: child, Dependencies: []Dependency{{IssueID: child.ID, DependsOnID: "bd-999"}}}
// after: create the parent first, then reference its real ID
parent, _ := uc.Create(ctx, parentParams, actor)
CreateIssueParams{Issue: child, Dependencies: []Dependency{{IssueID: child.ID, DependsOnID: parent.ID}}}
Defensive patterns

Strategy: validation

Validate before calling

for _, dep := range params.Dependencies {
    if dep.IssueID == "" || dep.DependsOnID == "" {
        return fmt.Errorf("dependency has empty endpoint: %+v", dep)
    }
    if _, err := uc.GetIssue(ctx, dep.DependsOnID); err != nil {
        return fmt.Errorf("dep target %s does not exist", dep.DependsOnID)
    }
}

Try / catch

var result CreateIssuesResult
result, err := uc.CreateIssues(ctx, params, actor)
if err != nil {
    var idxErr string
    if strings.Contains(err.Error(), "create: add dep ") {
        // parse edge from message and inspect wrapped cause
        idxErr = err.Error()
    }
    return fmt.Errorf("dependency insert failed: %v", idxErr)
}

Prevention

When it happens

Trigger: Calling Create/CreateIssues with Dependencies (or a graph plan) where dep.IssueID or dep.DependsOnID does not resolve to an inserted issue, the deps table insert violates a constraint, or the underlying DB/driver fails during Insert.

Common situations: Creating issues with dependencies on IDs that were never created or were deleted; typo'd issue IDs in a dependency list; DB constraint changes after schema migration; transient Dolt/storage failures during batch create.

Related errors


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