xai-org/grok-build · error
git fetch origin {oid} skipped: restore fetch budget exhaust
Error message
git fetch origin {oid} skipped: restore fetch budget exhausted What it means
fetch_if_missing performs a targeted `git fetch origin <oid>` during workspace restore, but only if a fetch budget (Duration) remains. When the passed timeout is exactly zero — the shared restore deadline has already been spent by earlier fetches or work — the library refuses to start a fetch it cannot bound and throws this error naming the oid it would have fetched.
Source
Thrown at crates/codegen/xai-grok-workspace/src/restore_fetch.rs:242
(SkippedInvalidOid, SkippedInvalidOid) => EnsureCommitsOutcome::SkippedInvalidOid,
}
}
pub(crate) fn fetch_if_missing<G: RestoreGit>(
repo: &Path,
oid: &str,
git: &G,
timeout: Duration,
) -> Result<FetchCommitOutcome> {
if !is_full_object_id(oid) {
tracing::warn!(oid = %oid, "restore_fetch: skipping non-oid refspec");
return Ok(FetchCommitOutcome::SkippedInvalidOid);
}
if git.has_object(repo, oid) {
return Ok(FetchCommitOutcome::AlreadyPresent);
}
if timeout.is_zero() {
bail!("git fetch origin {oid} skipped: restore fetch budget exhausted");
}
git.fetch_oid(repo, oid, timeout)?;
Ok(FetchCommitOutcome::Fetched)
}
/// Whether `git cat-file -t` resolves `spec` in `repo`.
pub fn git_object_exists(repo: &Path, spec: &str) -> bool {
let output = git_command()
.current_dir(repo)
.args(["cat-file", "-t", spec])
.stdout(Stdio::null())
.stderr(Stdio::null())
.output();
matches!(output, Ok(o) if o.status.success())
}
/// Fetch a checkout target (full oid or simple ref) if it is not already local.
///View on GitHub (pinned to bc7f02eddd)
Solutions
- Increase the restore fetch budget/deadline so time remains when this oid is fetched, or restore again — the budget is per-run and resets on retry
- Pre-populate the repo (git fetch origin <oid> manually or a fuller clone) so has_object returns true and no budget is consumed
- Reduce objects needing fetch: restore from a snapshot whose commits are already local, or check connectivity to origin to speed earlier fetches
- Treat as non-fatal per the API contract: the error does not mean the object is unreachable; log it and let checkout-strategy selection handle the missing commit
Example fix
// before: zero budget left, fetch refuses to start let outcome = fetch_if_missing(repo, oid, &git, Duration::ZERO)?; // after: compute a fresh budget (or retry the whole restore run) let budget = fresh_restore_fetch_budget(); // e.g. deadline - now, minus teardown reserve let outcome = fetch_if_missing(repo, oid, &git, budget)?;
Defensive patterns
Strategy: retry
Validate before calling
fn fetch_budget_ok(deadline: Instant) -> bool {
deadline.saturating_duration_since(Instant::now())
> RESTORE_FETCH_TEARDOWN_RESERVE // nonzero time must remain
}
// call before fetching: if (!fetch_budget_ok(deadline)) extend_budget_or_defer(); Try / catch
match fetch_if_missing(repo, oid, &git, remaining(deadline)) {
Ok(outcome) => outcome,
Err(e) if e.to_string().contains("restore fetch budget exhausted") => {
// budget spent: defer this oid to a fresh run or extend the deadline
defer_to_next_restore_run(oid);
FetchCommitOutcome::SkippedInvalidOid // per API: not necessarily unreachable
}
Err(e) => return Err(e),
} Prevention
- Size the restore fetch budget for your network: slow links/monorepos need larger deadlines
- Pre-fetch or fully clone snapshot commits so has_object passes and no budget is spent
- Check origin connectivity/latency before restore; flaky networks burn the budget on early fetches
- Monitor whether both head and base fetches are needed; restore from snapshots whose commits are already local
When it happens
Trigger: Calling fetch_if_missing (directly or via fetch_commit_if_missing / ensure_commits_reachable) after the shared restore-fetch budget is exhausted: earlier head/base fetches consumed the deadline, budget accounting reached zero, or a caller passes Duration::ZERO while the object is genuinely missing from the local repo.
Common situations: Restoring a snapshot repo where the head commit and the public base commit both need fetching on a slow network, exhausting the budget before the second fetch; restoring many commits sequentially against a large monorepo over a slow VPN; a hung first fetch whose teardown reserve consumed the remaining budget.
Related errors
- git fetch --no-tags origin {spec} timed out after {}s{}{}
- unsupported checkout target (need a full commit oid or a sim
- git fetch --no-tags origin {spec} failed ({status}): {stderr
- targeted fetch task failed: {e}
- fetch of base ref '{base}' failed: {fetch_out}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/6cfc2f1604f1c89e.
Report an issue: GitHub.