{"record":{"id":"007cb11d1f5cd799","repo":"gastownhall/beads","slug":"failed-to-update-s-in-s-v","errorCode":null,"errorMessage":"Failed to update %s in %s: %v","messagePattern":"Failed to update (.+?) in (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/tracker/engine.go","lineNumber":1152,"sourceCode":"\t\t\t\t\t\tif e.PushHooks.ContentEqual(issue, extIssue) {\n\t\t\t\t\t\t\t// Remote already matches: record the hash so future\n\t\t\t\t\t\t\t// runs skip the fetch above, not just the update.\n\t\t\t\t\t\t\te.recordPushHash(ctx, issue, extRef)\n\t\t\t\t\t\t\tstats.Skipped++\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if !extIssue.UpdatedAt.Before(issue.UpdatedAt) {\n\t\t\t\t\t\tstats.Skipped++ // Default: external is same or newer\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif _, err := e.Tracker.UpdateIssue(ctx, extID, pushIssue); err != nil {\n\t\t\t\tif isRateLimitExhausted(err) {\n\t\t\t\t\treturn stats, fmt.Errorf(\"sync aborted: %w\", err)\n\t\t\t\t}\n\t\t\t\te.warn(\"Failed to update %s in %s: %v\", issue.ID, e.Tracker.DisplayName(), err)\n\t\t\t\tstats.Errors++\n\t\t\t\tif isRateLimitedErr(err) {\n\t\t\t\t\te.warnRateLimitAbort(err, len(issues)-stats.Created-stats.Updated-stats.Skipped-stats.Errors)\n\t\t\t\t\treturn stats, nil\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Remember what we just pushed so the next sync can skip the fetch.\n\t\t\te.recordPushHash(ctx, issue, extRef)\n\t\t\tstats.Updated++\n\t\t} else {\n\t\t\tstats.Skipped++\n\t\t}\n\t}\n\n\tspan.SetAttributes(\n\t\tattribute.Int(\"sync.created\", stats.Created),\n\t\tattribute.Int(\"sync.updated\", stats.Updated),","sourceCodeStart":1134,"sourceCodeEnd":1170,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/tracker/engine.go#L1134-L1170","documentation":"During push, updating an issue that already exists in the external tracker failed. The engine logs a warning, increments stats.Errors, and continues with the next issue unless the failure is rate-limit related. This indicates the remote tracker rejected or could not process the update for this specific issue.","triggerScenarios":"e.Tracker.UpdateIssue(ctx, extID, pushIssue) returns an error for an issue with a valid external_ref — e.g. HTTP 4xx/5xx from the tracker API, validation rejection of field values, deleted remote issue, or (non-exhausted) rate limiting.","commonSituations":"Remote issue was deleted or moved in the tracker; auth token lacks edit permission on that project; description or field value violates tracker limits (e.g. too long); temporary 5xx or secondary rate limit from GitHub/Jira/Linear APIs.","solutions":["Read the wrapped tracker error to identify cause (404 → remote deleted, 403 → permissions, 422 → validation).","If the remote issue was deleted, either recreate it or clear the local external_ref (`bd update <id> --external-ref=\"\"`) so push re-creates it.","Fix field values that violate tracker constraints (truncate descriptions, valid status names).","Renew/repair the API token and confirm project-level edit permissions.","Re-run `bd sync` after fixing; only affected issues will retry since successful ones are hash-skipped."],"exampleFix":"// before: stale external_ref pointing at a deleted remote issue\n// after: clear the ref so the next push re-creates it\nbd update bd-123 --external-ref=\"\"\nbd push","handlingStrategy":"retry","validationCode":"// pre-flight: ensure the remote issue exists and is editable\nextID := tracker.ExtractIdentifier(derefStr(issue.ExternalRef))\nif extID == \"\" { skip(issue) }\nif _, err := tracker.FetchIssue(ctx, extID); err != nil {\n    log.Printf(\"remote for %s unreachable: %v\", issue.ID, err)\n}","typeGuard":null,"tryCatchPattern":"// exponential backoff on rate-limited or transient update failures\nfor i := 0; i < 5; i++ {\n    stats, err := engine.Sync(ctx, opts)\n    if err == nil && stats.Errors == 0 { return nil }\n    if isRateLimitedErr(err) || isTransientErr(err) {\n        time.Sleep(time.Duration(1<<i) * time.Second)\n        continue\n    }\n    return err\n}","preventionTips":["Verify external_refs still point at live remote issues","Keep tokens valid and project permissions current","Trim descriptions to tracker limits before push","Use push-hash/ContentEqual hooks to reduce API pressure"],"tags":["sync","tracker-api","rate-limit","permissions"],"backgroundTag":"tracker-update-rejected","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}