gastownhall/beads · warning

Failed to push issues in %s: %s

Error message

Failed to push issues in %s: %s

What it means

Batch-level variant of the real-push warning: the tracker's BatchPush returned an error item with no LocalID, so the engine cannot attribute the failure to a specific issue and reports it against the whole batch for that tracker. The push still returns stats with nil error; the message is the only diagnostic for what went wrong inside the batch.

Source

Thrown at internal/tracker/engine.go:1016

				return stats, nil
			}
		} else {
			batchResult, err := batchTracker.BatchPush(ctx, pushIssues, forceIDs)
			if err != nil {
				return nil, fmt.Errorf("batch pushing issues: %w", err)
			}
			e.applyBatchPushResult(ctx, batchResult)
			stats.Created += len(batchResult.Created)
			stats.Updated += len(batchResult.Updated)
			stats.Skipped += len(batchResult.Skipped)
			stats.Errors += len(batchResult.Errors)
			stats.Warnings = append(stats.Warnings, batchResult.Warnings...)
			for _, item := range batchResult.Errors {
				if item.LocalID != "" {
					e.warn("Failed to push %s in %s: %s", item.LocalID, e.Tracker.DisplayName(), item.Message)
					continue
				}
				e.warn("Failed to push issues in %s: %s", e.Tracker.DisplayName(), item.Message)
			}
			return stats, nil
		}
	}

	for _, issue := range issues {
		// Limit to parent and its descendants if requested.
		if descendantSet != nil && !descendantSet[issue.ID] {
			stats.Skipped++
			continue
		}
		// Skip filtered types/states/ephemeral
		if !e.shouldPushIssue(issue, opts) {
			stats.Skipped++
			continue
		}

		// ShouldPush hook: custom filtering (prefix filtering, etc.)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the message for cause; re-authenticate the tracker if it indicates 401/403/bad credentials.
  2. If rate limited, wait for the reset window and re-push; unchanged items are skipped via push hashes so only failures retry.
  3. Verify the target repo/project still exists and the configured name matches after any rename.
  4. For network errors, re-run the sync — the batch is resumable since successfully pushed items are skipped on the next pass.

Example fix

// before: renamed repo makes whole batch fail
// tracker: github:acme/old-repo
// after: update config to current name
// tracker: github:acme/new-repo
Defensive patterns

Strategy: retry

Validate before calling

// Preflight: ensure tracker auth and target are valid before batch push
// (e.g. call a cheap read API or the adapter's Ping/health method):
if err := preflightTracker(ctx, tracker); err != nil {
    return fmt.Errorf("aborting batch push, tracker not ready: %w", err)
}

Type guard

batchTracker, ok := tracker.(BatchPushTracker) // knowing the batch path is used helps interpret batch-level (no-LocalID) failures

Try / catch

stats, err := engine.Sync(ctx, opts)
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) || isRateLimit(err) {
        time.Sleep(backoff) // wait out rate limit / transient outage
        stats, err = engine.Sync(ctx, opts)
    }
    return err
}
// batch-level (no LocalID) failures appear only in stats.Warnings

Prevention

When it happens

Trigger: Non-dry-run BatchPush call returning an item whose LocalID is empty — adapter-level failures such as authentication errors, network/timeout mid-batch, rate limit exhaustion across the batch, or the remote API rejecting the batch request itself.

Common situations: Token expired mid-sync, repository archived or renamed so the batch target is invalid, network interruption during a large batch, or API rate limits hit partway through the batch leaving remaining items unpushed.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/489684eba4c9dca7. Report an issue: GitHub.