gastownhall/beads · error

creating Linear milestone epic %q: %w

Error message

creating Linear milestone epic %q: %w

What it means

Wraps st.CreateIssue failures when persisting a new Linear milestone epic. The epic (type epic, external ref set, merged metadata) failed to be written to storage; the error includes the epic title and root cause via %w.

Source

Thrown at cmd/bd/linear.go:642

	}

	externalRef := ref
	epic := &types.Issue{
		Title:       title,
		Description: description,
		Status:      types.StatusOpen,
		Priority:    2,
		IssueType:   types.TypeEpic,
		ExternalRef: &externalRef,
		Metadata:    metadata,
	}
	if generateID != nil {
		if err := generateID(ctx, epic); err != nil {
			return "", fmt.Errorf("generating Linear milestone epic ID: %w", err)
		}
	}
	if err := st.CreateIssue(ctx, epic, actor); err != nil {
		return "", fmt.Errorf("creating Linear milestone epic %q: %w", title, err)
	}
	return ref, nil
}

func findLinearMilestoneEpic(ctx context.Context, st storage.Storage, ref, milestoneID, title string) (*types.Issue, error) {
	if existing, err := st.GetIssueByExternalRef(ctx, ref); err == nil {
		return existing, nil
	} else if !errors.Is(err, storage.ErrNotFound) {
		return nil, err
	}

	issues, err := st.SearchIssues(ctx, "", types.IssueFilter{})
	if err != nil {
		return nil, fmt.Errorf("searching local issues for Linear milestone %s: %w", milestoneID, err)
	}
	for _, issue := range issues {
		if issueHasLinearMilestoneID(issue, milestoneID) {
			return issue, nil

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the wrapped storage error; if it's a duplicate/uniqueness failure, re-run the sync — it will find the existing epic via GetIssueByExternalRef
  2. Ensure only one sync runs per workspace at a time
  3. Verify database connectivity and retry
Defensive patterns

Strategy: retry

Validate before calling

// avoid duplicate-create races by checking the ref first
if _, err := st.GetIssueByExternalRef(ctx, externalRef); err == nil {
    return "", nil // epic already exists; skip create
}

Try / catch

if err := st.CreateIssue(ctx, epic, actor); err != nil {
    if isDuplicate(err) { return findLinearMilestoneEpic(ctx, st, ref, milestoneID, title) }
    return "", fmt.Errorf("creating Linear milestone epic %q: %w", title, err)
}

Prevention

When it happens

Trigger: ensureLinearMilestoneEpic found no existing epic for the milestone external ref and attempted creation; storage rejects the write — duplicate external ref race, DB unavailable, validation failure on the issue payload.

Common situations: Two concurrent syncs both creating the same milestone epic (unique-constraint race); database locked/offline; invalid characters in title from Linear flowing into storage constraints.

Related errors


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