# bootstrap: address Copilot review — wording/naming for timeout path

`0288391`→[main](/content/gh/entireio/git-sync/commits/main/index.html)·

Soph·1mo ago·1 file·+13 added/-14 removed

The one-shot retry path and the mid-batch subdivision now fire on
receive-pack deadlines (408/504), not just size rejections, so the
rejection-centric log message, the `sizeIssue` variable name, and the
"rejected" wording in the actionable error were all misleading.

- Log message: "after target rejection" → "after batchable push failure"
  (the per-call `reason` field already distinguishes timeout vs rejection).
- Rename `sizeIssue` → `subdivide`, keyed on the shared remedy.
- Actionable error: "rejected the pack" → "could not receive the pack —
too large, or too slow to receive within its deadline".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

## Sessions

460bf1c3228fView transcript

### Changes

1

- internal/strategy/bootstrap

- Mbootstrap.go+13/-14

```
184 unmodified lines

185
186
187
188
188
189
190
191
310 unmodified lines

502
503
504
505
506
507
508
509
510
511
505
506
507
508
509
510
511
512
513
5 unmodified lines

519
520
521
523
522
523
525
524
525
526
527
946 unmodified lines

1474
1475
1476
1478
1477
1478
1479
1480
6 unmodified lines

1487
1488
1489
1491
1492
1493
1490
1491
1492
1493
1494
1495

184 unmodified lines

if isTargetPushDeadlineError(pushErr) {
		reason = "target push timed out"
	}
	p.log("bootstrap retrying with batched mode after target rejection",
	p.log("bootstrap retrying with batched mode after batchable push failure",
		"target_max_pack_bytes", autoBatch, "reason", reason)
	p.notice(fmt.Sprintf("%s — switching to batched mode (limit %s)",
		reason, humanBytes(autoBatch)))
310 unmodified lines

abortedEarly := observer.Aborted()
		if pushErr != nil {
			_ = packReader.Close()
			// Treat abortedEarly the same as a body-limit error:
			// both indicate "this pack is too big for the target",
			// just one is detected by the server and one by us. A
			// receive-pack deadline (408/504) lands here too — a
			// checkpoint that times out is also too big for this
			// target/link, and subdividing makes each push finish sooner.
			sizeIssue := abortedEarly || isBatchableTargetPushError(pushErr)
			// A pack too big for the target is the unifying signal here,
			// whether the server announced it (413 body limit), we
			// detected it ourselves (abortedEarly), or the target ran out
			// of time receiving it (408/504 deadline). All three are fixed
			// the same way: subdivide so each push is smaller and faster.
			subdivide := abortedEarly || isBatchableTargetPushError(pushErr)
		p.log("bootstrap batch push failed",
			"branch", batch.Plan.TargetRef.String(),
			"batch", idx+1,
			"objects_sent", objectsSent,
			"total_objects_in_pack", totalObjects,
			"aborted_early", abortedEarly,
			"will_subdivide", sizeIssue && len(batch.chain) > 0,
			"will_subdivide", subdivide && len(batch.chain) > 0,
			"error", pushErr.Error())
		if sizeIssue && len(batch.chain) > 0 {
		if subdivide && len(batch.chain) > 0 {
			parsedLimit := targetBodyLimit(pushErr)
			limit := p.TargetMaxPack
			if parsedLimit > 0 {
946 unmodified lines

}

// actionableTargetPushError augments a one-shot push failure with guidance
// when the target rejected the pack for being too large or slow but batched
// when the target couldn't receive the pack — too large or too slow — but batched
// bootstrap couldn't take over — which, on the one-shot path, means the source
// can't serve the protocol-v2 fetch filter that checkpointing requires. The
// extra context tells the user why the obvious knob (--target-max-pack-bytes)

if p.SourceService != nil && p.SourceService.SupportsBootstrapBatch() {
	return err
}
return fmt.Errorf("%w (target rejected the pack as too large or too slow to receive; "+
	"batched bootstrap could split it into smaller pushes, but the source does not "+
	"support the protocol-v2 fetch filter batched bootstrap requires)", err)
return fmt.Errorf("%w (target could not receive the pack — too large, or too slow to "+
	"receive within its deadline; batched bootstrap could split it into smaller pushes, "+
	"but the source does not support the protocol-v2 fetch filter batched bootstrap requires)", err)
}

func targetBodyLimit(err error) int64 {
```
