{"record":{"id":"12f096a168426dad","repo":"gastownhall/beads","slug":"gitlab-dependency-link-sync-v","errorCode":null,"errorMessage":"GitLab dependency link sync: %v","messagePattern":"GitLab dependency link sync: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/bd/gitlab.go","lineNumber":682,"sourceCode":"\t\tresolver := gitlab.NewLinkResolver(client)\n\t\tres := resolver.PushLinks(ctx, linkData.DesiredLinks, gitlab.PushLinkOptions{\n\t\t\tDryRun: dryRun,\n\t\t\tOnPlan: func(link gitlab.DependencyLink) {\n\t\t\t\tif !jsonOutput {\n\t\t\t\t\t_, _ = fmt.Fprintf(out, \"  [dry-run] Would create GitLab dependency link: #%d %s #%d\\n\",\n\t\t\t\t\t\tlink.SourceIID, link.LinkType, link.TargetIID)\n\t\t\t\t}\n\t\t\t},\n\t\t})\n\t\tlinksPushed = res.Created\n\t\tlinksLicenseSkipped = res.LicenseSkipped\n\t\t// Curated, license-aware degradation: one actionable line instead of\n\t\t// a raw per-link API error, kept distinct from genuine failures.\n\t\tif res.LicenseSkipped > 0 {\n\t\t\twarn(gitLabLicenseSkipMessage(res.LicenseSkipped))\n\t\t}\n\t\tfor _, err := range res.Errors {\n\t\t\twarn(fmt.Sprintf(\"GitLab dependency link sync: %v\", err))\n\t\t}\n\t}\n\n\tif len(linkData.ScopedIssues) > 0 {\n\t\tcount, errs := gt.PushEpicMilestones(ctx, linkData.ScopedIssues, gitlab.EpicMilestoneOptions{\n\t\t\tDryRun: dryRun,\n\t\t\tOnPlan: func(issueID string, issueIID int, milestoneID int) {\n\t\t\t\tif !jsonOutput {\n\t\t\t\t\t_, _ = fmt.Fprintf(out, \"  [dry-run] Would set GitLab milestone %d on %s (#%d)\\n\",\n\t\t\t\t\t\tmilestoneID, issueID, issueIID)\n\t\t\t\t}\n\t\t\t},\n\t\t})\n\t\tmilestonesUpdated = count\n\t\tfor _, err := range errs {\n\t\t\twarn(fmt.Sprintf(\"GitLab epic milestone sync: %v\", err))\n\t\t}\n\t}","sourceCodeStart":664,"sourceCodeEnd":700,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/gitlab.go#L664-L700","documentation":"During GitLab sync/push, dependency-link synchronization failures reported by the GitLab linker are emitted one per line as 'GitLab dependency link sync: %v' warnings via the warn callback. The comment above the loop notes this is a curated degradation: the per-link API error is surfaced compactly and kept distinct from genuine sync failures, which do not abort the overall run.","triggerScenarios":"res.Errors non-empty after pushing dependency links — GitLab API errors creating/updating issue links (403 insufficient permissions, 404 issue deleted, 409 conflict, Epic linkage unsupported on the instance/license tier).","commonSituations":"Token lacking api scope or reporter-level permissions on target issues; issues closed/deleted in GitLab between bead creation and push; self-managed GitLab instances without the license feature for the link type.","solutions":["Read each wrapped %v error to identify the failing issue link and root cause.","Grant the GitLab token the required api scope and at least Reporter role on the target project.","Re-run `bd gitlab sync` (or push) after fixing the cause; remove or correct beads links pointing at deleted GitLab issues.","If a license-skip message also appears, note those links were intentionally skipped, not failed."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"res := pushGitLabDependencyLinks(ctx, ...)\nfor _, e := range res.Errors {\n\tlog.Warn(fmt.Sprintf(\"GitLab dependency link sync: %v\", e))\n}\n// treat as non-fatal; re-run sync after fixing permissions/stale links","preventionTips":["Use a GitLab token with api scope and Reporter+ access to target projects.","Clean up beads links pointing at deleted GitLab issues before push.","Check the license-skip notice to distinguish intentional skips from real failures."],"tags":["gitlab","sync","dependencies","warning"],"backgroundTag":"link-sync-conflict","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}