{"record":{"id":"6f1833475fa4cfa4","repo":"gastownhall/beads","slug":"failed-to-push-s-in-s-s","errorCode":null,"errorMessage":"Failed to push %s in %s: %s","messagePattern":"Failed to push (.+?) in (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/tracker/engine.go","lineNumber":1013,"sourceCode":"\t\t\t\t\t}\n\t\t\t\t\te.warn(\"Failed to preview pushes in %s: %s\", e.Tracker.DisplayName(), item.Message)\n\t\t\t\t}\n\t\t\t\treturn stats, nil\n\t\t\t}\n\t\t} else {\n\t\t\tbatchResult, err := batchTracker.BatchPush(ctx, pushIssues, forceIDs)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"batch pushing issues: %w\", err)\n\t\t\t}\n\t\t\te.applyBatchPushResult(ctx, batchResult)\n\t\t\tstats.Created += len(batchResult.Created)\n\t\t\tstats.Updated += len(batchResult.Updated)\n\t\t\tstats.Skipped += len(batchResult.Skipped)\n\t\t\tstats.Errors += len(batchResult.Errors)\n\t\t\tstats.Warnings = append(stats.Warnings, batchResult.Warnings...)\n\t\t\tfor _, item := range batchResult.Errors {\n\t\t\t\tif item.LocalID != \"\" {\n\t\t\t\t\te.warn(\"Failed to push %s in %s: %s\", item.LocalID, e.Tracker.DisplayName(), item.Message)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\te.warn(\"Failed to push issues in %s: %s\", e.Tracker.DisplayName(), item.Message)\n\t\t\t}\n\t\t\treturn stats, nil\n\t\t}\n\t}\n\n\tfor _, issue := range issues {\n\t\t// Limit to parent and its descendants if requested.\n\t\tif descendantSet != nil && !descendantSet[issue.ID] {\n\t\t\tstats.Skipped++\n\t\t\tcontinue\n\t\t}\n\t\t// Skip filtered types/states/ephemeral\n\t\tif !e.shouldPushIssue(issue, opts) {\n\t\t\tstats.Skipped++\n\t\t\tcontinue","sourceCodeStart":995,"sourceCodeEnd":1031,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/tracker/engine.go#L995-L1031","documentation":"Warning logged during a real (non-dry-run) batch push when the tracker's BatchPush call succeeds at the transport level but reports a per-issue error with a non-empty LocalID. The engine counts the item in stats.Errors, logs which local issue failed to push to which tracker, and continues processing. The overall sync still returns success; failed items are reported as warnings, not a fatal error.","triggerScenarios":"Calling Sync/doPush against a BatchPushTracker where BatchPush returns error items carrying LocalID — e.g. remote update rejected (stale external_ref, 422 validation), remote item deleted or moved, permission denied on that specific issue, or per-item rate limit.","commonSituations":"A GitHub issue was closed/deleted remotely so the update 404s; labels or milestones referenced locally don't exist; the token lacks write access to the target repo; duplicate title detection rejecting a create.","solutions":["Fix the named issue locally per the message (repair external_ref, create the missing label/state, adjust the field that failed validation) and re-run push.","If the remote item no longer exists, clear issue.ExternalRef so the next push recreates it.","Grant the token/app write permissions on the target repository or project if the message indicates forbidden/403.","Re-run the push after transient (rate limit, 5xx) causes — stats.Errors tells you how many items need attention."],"exampleFix":"// before: update against deleted remote item fails\n\"external_ref\": \"github:42\" // deleted upstream\n// after\nbd update BD-42 --external-ref=\"\"  # next push recreates the remote issue","handlingStrategy":"retry","validationCode":"// Validate each candidate issue before push:\nfor _, it := range pushIssues {\n    if it.ExternalRef != \"\" && !tracker.IsExternalRef(it.ExternalRef) {\n        return fmt.Errorf(\"%s: external_ref %q is not a valid remote link\", it.ID, it.ExternalRef)\n    }\n}","typeGuard":"func isPerItemFailure(item BatchErrorItem) bool { return item.LocalID != \"\" } // true => retry just that issue after fixing data","tryCatchPattern":"stats, err := engine.Sync(ctx, opts)\nif err != nil {\n    return err // whole-batch/transport failure\n}\nif stats.Errors > 0 {\n    // stats.Warnings name the failing LocalIDs; repair data, then re-run.\n    // Re-push is safe: unchanged items skip via stored push hashes.\n    stats, err = engine.Sync(ctx, opts)\n}","preventionTips":["Re-run pushes after failures — idempotent skip logic means only failed items retry.","Fix remote-side prerequisites (labels, states, permissions) surfaced in the warning before retrying.","Clear external_ref for items whose remote counterpart was deleted so they are recreated.","Monitor stats.Errors after every sync and treat non-zero as a follow-up queue."],"tags":["sync","push","batch-push","tracker-adapter"],"backgroundTag":"batch-item-push-rejected","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}