gastownhall/beads · critical

migration failed: %w

Error message

migration failed: %w

What it means

This error wraps failures from executeMigration, the step that actually rewrites each issue's repo field from p.from to p.to after the user confirms the plan. It means the write phase of the migration failed partway, potentially leaving some issues migrated and others not. The wrapped error carries the storage-level cause.

Source

Thrown at cmd/bd/migrate_issues.go:189

	// Step 5: Build migration plan
	plan := buildMigrationPlan(candidates, migrationSet, dependencyStats, orphans, p.from, p.to)

	// Step 6: Display plan
	if err := displayMigrationPlan(plan, p.dryRun); err != nil {
		return err
	}

	// Step 7: Execute migration if not dry-run
	if !p.dryRun {
		if !p.yes && !jsonOutput {
			if !confirmMigration(plan) {
				fmt.Println("Migration canceled")
				return nil
			}
		}

		if err := executeMigration(ctx, s, migrationSet, p.to); err != nil {
			return fmt.Errorf("migration failed: %w", err)
		}

		if jsonOutput {
			return outputJSON(map[string]interface{}{
				"success": true,
				"message": fmt.Sprintf("Migrated %d issues from %s to %s", len(migrationSet), p.from, p.to),
				"plan":    plan,
			})
		}
		fmt.Printf("\n✓ Successfully migrated %d issues from %s to %s\n", len(migrationSet), p.from, p.to)
	}

	return nil
}

func validateRepos(ctx context.Context, s storage.DoltStorage, from, to string, strict bool) error {
	// migrate-issues is a round-trip path — opt out of BEADS_MAX_ROWS
	// (designer §4.1) so a misconfigured env doesn't abort migration.

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped error to see how far the migration got
  2. Re-run the same command — candidates are re-derived and already-migrated issues no longer match --from, making the retry idempotent
  3. Restore from the Dolt history / backup if a partial state is unacceptable
  4. Migrate in smaller filter batches to keep each write transaction small

Example fix

// before: one giant batch can fail mid-way
if err := executeMigration(ctx, s, migrationSet, p.to); err != nil {
    return fmt.Errorf("migration failed: %w", err)
}
// after: migrate in filtered batches so retries stay small
cmd bd migrate-issues --from old --to new --label backend
cmd bd migrate-issues --from old --to new --label frontend
Defensive patterns

Strategy: try-catch

Validate before calling

// back up before executing
bd dolt push   # or otherwise snapshot the database
bd migrate-issues --from old --to new --dry-run  # confirm the plan size is sane

Try / catch

if err := runMigrate(); err != nil {
    if strings.Contains(err.Error(), "migration failed") {
        log.Printf("migration aborted mid-write: %v — retry is idempotent (already-migrated issues no longer match --from)", errors.Unwrap(err))
    }
    return err
}

Prevention

When it happens

Trigger: executeMigration(ctx, s, migrationSet, p.to) returns an error after plan confirmation, while batch-updating issue repo assignments.

Common situations: Disk full or database write failure mid-batch; another bd process mutating the same rows concurrently; context cancellation (Ctrl-C) during a long migration; transaction size limits on very large migration sets.

Related errors


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