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

  1. 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
  2. Pre-populate the repo (git fetch origin <oid> manually or a fuller clone) so has_object returns true and no budget is consumed
  3. Reduce objects needing fetch: restore from a snapshot whose commits are already local, or check connectivity to origin to speed earlier fetches
  4. 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

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


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/6cfc2f1604f1c89e. Report an issue: GitHub.