{"record":{"id":"377216deed26c331","repo":"gastownhall/beads","slug":"failed-to-preview-push-s-in-s-s","errorCode":null,"errorMessage":"Failed to preview push %s in %s: %s","messagePattern":"Failed to preview push (.+?) in (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/tracker/engine.go","lineNumber":993,"sourceCode":"\t\tstats.Skipped += skipped\n\t\tif len(pushIssues) == 0 {\n\t\t\treturn stats, nil\n\t\t}\n\t\tif opts.DryRun {\n\t\t\tif dryRunner, ok := e.Tracker.(BatchPushDryRunner); ok {\n\t\t\t\tbatchResult, err := dryRunner.BatchPushDryRun(ctx, pushIssues, forceIDs)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"previewing batch push: %w\", err)\n\t\t\t\t}\n\t\t\t\te.renderBatchDryRun(pushIssues, batchResult)\n\t\t\t\tstats.Created += len(batchResult.Created)\n\t\t\t\tstats.Updated += len(batchResult.Updated)\n\t\t\t\tstats.Skipped += len(batchResult.Skipped)\n\t\t\t\tstats.Errors += len(batchResult.Errors)\n\t\t\t\tstats.Warnings = append(stats.Warnings, batchResult.Warnings...)\n\t\t\t\tfor _, item := range batchResult.Errors {\n\t\t\t\t\tif item.LocalID != \"\" {\n\t\t\t\t\t\te.warn(\"Failed to preview push %s in %s: %s\", item.LocalID, e.Tracker.DisplayName(), item.Message)\n\t\t\t\t\t\tcontinue\n\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 {","sourceCodeStart":975,"sourceCodeEnd":1011,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/tracker/engine.go#L975-L1011","documentation":"This is a warning emitted by the push engine's dry-run (preview) path when the tracker adapter's BatchPushDryRun returned a per-issue error entry in batchResult.Errors. The engine does not abort; it logs the failure for the specific local issue (item.LocalID) against the external tracker's display name and continues with the rest of the batch. It means one issue in your preview could not be simulated — e.g. validation or API lookup failed for that item only.","triggerScenarios":"Running a dry-run push (opts.DryRun=true) against a tracker implementing BatchPushDryRunner where BatchPushDryRun succeeds overall but returns an error item with a non-empty LocalID — e.g. the tracker API rejected that one issue during the preview (invalid state/label, missing external ref resolution, per-item validation).","commonSituations":"Previewing `bd sync --dry-run` against GitHub/Linear/Jira where one issue references a state or label that doesn't exist remotely, an issue's external_ref points to a deleted remote item, or a per-issue field violates the tracker's limits (title length, missing required field).","solutions":["Read the %s message in the warning to see which item failed; fix that issue's data (title length, state, external_ref) locally and re-run the dry-run.","Verify the remote tracker configuration (states, labels, project/board IDs) matches what the local issues reference.","If the external_ref is stale, clear it or use force-push IDs so the item is treated as a create instead of an update.","Check the adapter implementation's BatchPushDryRun to confirm why it returned a per-item error instead of skipping."],"exampleFix":"// before: stale external_ref fails preview update\nissue.ExternalRef = \"github:does-not-exist-999\"\n// after: reset ref so preview treats it as a create\nissue.ExternalRef = \"\" // or re-link to the correct remote issue","handlingStrategy":"validation","validationCode":"// Before dry-run/push, sanity-check each issue that will be sent:\nfunc validateForPush(issue *types.Issue) error {\n    if issue.Title == \"\" || len(issue.Title) > 256 {\n        return fmt.Errorf(\"issue %s: title missing or too long\", issue.ID)\n    }\n    if issue.ExternalRef != \"\" && !tracker.IsExternalRef(issue.ExternalRef) {\n        return fmt.Errorf(\"issue %s: stale external_ref %q\", issue.ID, issue.ExternalRef)\n    }\n    return nil\n}","typeGuard":"func hasBatchItemLocalID(item BatchErrorItem) bool { return item.LocalID != \"\" } // non-empty LocalID => per-issue diagnostics available","tryCatchPattern":"stats, err := engine.Sync(ctx, opts)\nif err != nil {\n    return fmt.Errorf(\"sync aborted: %w\", err)\n}\nfor _, w := range stats.Warnings { // preview item failures land here\n    log.Warnf(\"preview warning: %s\", w)\n}\nif stats.Errors > 0 { /* inspect and fix named issues, then re-run */ }","preventionTips":["Keep external_ref values in sync with the remote tracker; clear refs when the remote item is deleted.","Run the dry-run first and fix every preview warning before the real push.","Validate titles/labels/states against the tracker's actual configuration before syncing.","Keep tracker auth tokens fresh and scoped for write access."],"tags":["sync","dry-run","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"}