gastownhall/beads · error

generating Linear milestone epic ID: %w

Error message

generating Linear milestone epic ID: %w

What it means

When creating a new Linear milestone epic, an optional generateID callback assigns the issue ID; any error it returns is wrapped as "generating Linear milestone epic ID: %w". This happens before CreateIssue, so nothing has been persisted yet.

Source

Thrown at cmd/bd/linear.go:638

				return "", fmt.Errorf("updating Linear milestone epic %s: %w", existing.ID, err)
			}
		}
		return ref, nil
	}

	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)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped error from your generateID implementation
  2. Verify the ID allocation backend (counter/sequence storage) is healthy
  3. Retry the sync once ID generation works; no epic was created on failure so retry is clean
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the generator works before starting the sync
if generateID != nil {
    probe := &types.Issue{Title: "probe"}
    if err := generateID(ctx, probe); err != nil {
        return "", fmt.Errorf("ID generator unhealthy: %w", err)
    }
}

Try / catch

if err := generateID(ctx, epic); err != nil {
    var gerr *IDGenError
    if errors.As(err, &gerr) { /* fall back to default ID scheme or abort */ }
    return "", fmt.Errorf("generating Linear milestone epic ID: %w", err)
}

Prevention

When it happens

Trigger: ensureLinearMilestoneEpic creates a fresh epic for a milestone not yet in beads, and the injected generateID function (custom ID generation, e.g. prefix/sequence logic) returns an error — sequence exhaustion, storage-backed ID allocation failure.

Common situations: Custom ID generator backed by a DB counter that fails or times out; misconfigured generateID in test harnesses; ID prefix collisions configured in workspace settings.

Related errors


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