gastownhall/beads · warning
Link sync ADO #%d: %v
Error message
Link sync ADO #%d: %v
What it means
pushADOLinks collects per-link errors returned by resolver.PushLinks and reports each as a 'Link sync ADO #N' warning, both appended to the returned warnings slice and passed to the warn callback. Individual failed relations do not abort the sync; the count of successfully applied links is reduced accordingly.
Source
Thrown at cmd/bd/ado.go:857
continue
}
// Fetch current ADO work item to get existing relations.
adoClient := at.ADOClient()
items, ferr := adoClient.FetchWorkItems(ctx, []int{workItemID})
if ferr != nil || len(items) == 0 {
if warn != nil {
warn(fmt.Sprintf("Failed to fetch ADO #%d for link sync: %v", workItemID, ferr))
}
continue
}
errs := resolver.PushLinks(ctx, workItemID, items[0].Relations, desired, managedTargets)
for _, e := range errs {
msg := fmt.Sprintf("Link sync ADO #%d: %v", workItemID, e)
warnings = append(warnings, msg)
if warn != nil {
warn(msg)
}
}
linkCount += len(desired) - len(errs)
}
return linkCount, warnings
}
// buildADOPullHooks creates PullHooks for ADO-specific pull behavior.
// When bootstrapMatch is true, incoming ADO items are matched against existing
// local issues by external_ref, source_system, and heuristic before creating
// duplicates. When noCreate is true, unmatched items are skipped entirely.
func buildADOPullHooks(ctx context.Context, at *ado.Tracker, bootstrapMatch, noCreate bool, matchCount *int, warn func(string)) *tracker.PullHooks {
prefix := "bd"
// YAML config takes precedence — in shared-server mode the DB
// may belong to a different project (GH#2469).
if p := config.GetString("issue-prefix"); p != "" {
prefix = pView on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped %v error for each offending link (permission vs conflict vs invalid relation).
- Grant the sync identity permission to edit the affected ADO work items.
- Re-run sync to resolve transient revision conflicts; resolve duplicates/stale links in beads first if the error indicates invalid relations.
Defensive patterns
Strategy: fallback
Try / catch
count, warnings := pushADOLinks(ctx, ...)
for _, w := range warnings {
if strings.HasPrefix(w, "Link sync ADO #") {
log.Warn(w) // retry or escalate per-link
}
} Prevention
- Ensure the sync identity has edit permission on all mapped ADO work items.
- Avoid concurrent edits to the same ADO work items during sync.
- Re-run sync to clear transient revision conflicts.
When it happens
Trigger: resolver.PushLinks rejects or fails to write some relations — e.g. ADO rejects a relation type, permission denied on the work item, stale concurrent revision (409), or one desired link's counterpart no longer exists.
Common situations: Service account lacking permissions to edit certain ADO work items; work-item revision conflicts from concurrent edits; relation types unsupported by the target ADO process template.
Related errors
- Failed to fetch ADO #%d for link sync: %v
- initializing Azure DevOps tracker: %w
- invalid pull filter: %w
- Ambiguous bootstrap match for ADO #%s: %d candidates
- GitLab dependency link sync: %v
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/9b8f9fc3f3ad5a62.
Report an issue: GitHub.