gastownhall/beads · warning

Failed to update %s during reimport: %v

Error message

Failed to update %s during reimport: %v

What it means

The external version was fetched and mapped successfully, but applying the scalar field updates (title, description, priority, status, metadata) to the local issue inside a lifecycle transaction failed. The local issue keeps its pre-reimport values despite conflict resolution choosing the external side.

Source

Thrown at internal/tracker/engine.go:1309

		return
	}

	updates := map[string]interface{}{
		"title":       conv.Issue.Title,
		"description": conv.Issue.Description,
		"priority":    conv.Issue.Priority,
		"status":      string(conv.Issue.Status),
	}
	if extIssue.Metadata != nil {
		if raw, err := json.Marshal(extIssue.Metadata); err == nil {
			updates["metadata"] = json.RawMessage(raw)
		}
	}

	if err := e.Store.RunInIssueLifecycleTransaction(ctx, fmt.Sprintf("bd: reimport update %s", c.IssueID), func(tx storage.IssueLifecycleTransaction) error {
		return applyPullIssueFields(ctx, tx, c.IssueID, updates, e.Actor)
	}); err != nil {
		e.warn("Failed to update %s during reimport: %v", c.IssueID, err)
	}
}

// createDependencies creates dependencies from the pending list, matching
// external IDs to local issue IDs. Returns the number of dependencies that
// failed to resolve or create.
func (e *Engine) createDependencies(ctx context.Context, deps []DependencyInfo) int {
	if len(deps) == 0 {
		return 0
	}

	resolveIssue, err := e.dependencyIssueResolver(ctx, nil)
	if err != nil {
		e.warn("Failed to build dependency resolver: %v", err)
		return len(deps)
	}

	errCount := 0

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the storage error text (lock, constraint, validation) and fix accordingly.
  2. If the status is rejected, verify the tracker's field mapper maps remote states to valid bd statuses.
  3. Re-run `bd sync` to retry the reimport once storage is healthy.
  4. Ensure no other bd process holds the write lock during sync.
  5. If the issue was deleted locally, drop the conflict expectation and recreate/delete as needed.

Example fix

// before: invalid status from remote mapping causes tx failure
// after: align the mapper's status mapping with bd's allowed statuses
// e.g. map "In Progress" -> "in_progress" instead of "wip"
Defensive patterns

Strategy: validation

Validate before calling

// ensure mapped remote statuses are valid bd statuses before pulling conflicts
valid := map[string]bool{"open": true, "in_progress": true, "closed": true}
if !valid[strings.ToLower(extStatus)] {
    log.Printf("remote status %q unmapped — update the field mapper", extStatus)
}

Try / catch

// storage errors during reimport: wait, then re-run sync (idempotent)
stats, err := engine.Sync(ctx, opts)
if stats != nil && stats.Errors > 0 && isStorageErr(err) {
    time.Sleep(2 * time.Second)
    engine.Sync(ctx, opts)
}

Prevention

When it happens

Trigger: e.Store.RunInIssueLifecycleTransaction(...applyPullIssueFields...) returns an error when reimporting a conflict — transaction begin/commit failure, storage lock, validation rejection of field values (e.g. invalid status), or the local issue having been deleted mid-sync.

Common situations: Local DB locked by another bd process; status value from the tracker doesn't map to a valid local status enum; issue deleted concurrently; disk-full during transaction commit.

Related errors


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