alibaba/open-code-review · error

load diffs: %w

Error message

load diffs: %w

What it means

Agent.Run in internal/agent/agent.go wraps a failure from a.loadDiffs (diff parsing) as 'load diffs: %w'. This is the step-1 failure of the review pipeline: the agent could not resolve the review input (parse diffs from git). Before returning, the agent records a run-level input failure in the session manifest and finalizes the session so a failed session_end is still persisted.

Source

Thrown at internal/agent/agent.go:299

	// so affinity keys stay per-conversation, the granularity provider prompt caches actually reuse prefixes at.
	ctx = llm.ContextWithSessionKey(ctx, a.SessionID())

	// Step 1: Parse diffs
	ctx, diffSpan := telemetry.StartSpan(ctx, "diff.parse")
	if err := a.loadDiffs(ctx); err != nil {
		diffSpan.End()
		// The builder already exists (agent.New created session + manifest), but
		// no item was selected yet. Record the run-level input failure at this
		// trigger point, then finalize and persist so the run still emits a
		// session_end with a failed manifest instead of looking aborted.
		if b := a.session.Manifest(); b != nil {
			_ = b.SetRunFailure(session.RunFailureInput, "failed to resolve review input")
		}
		manifestErr := a.finalizeManifest()
		// Keep the load failure as the primary cause, but never drop a persistence
		// failure: a run that could not even write its failed session_end must
		// report both rather than silently prefer one.
		loadErr := fmt.Errorf("load diffs: %w", err)
		if ferr := a.session.Finalize(); ferr != nil {
			manifestErr = errors.Join(manifestErr, fmt.Errorf("finalize session: %w", ferr))
		}
		if manifestErr != nil {
			return nil, errors.Join(loadErr, manifestErr)
		}
		return nil, loadErr
	}
	telemetry.SetAttr(diffSpan, "files.changed", len(a.diffs))
	telemetry.SetAttr(diffSpan, "lines.inserted", int64(a.totalInsertions))
	telemetry.SetAttr(diffSpan, "lines.deleted", int64(a.totalDeletions))
	diffSpan.End()

	// Build the read-only DiffMap from ALL parsed diffs (before filtering)
	// so the LLM can query diffs of related but filtered-out files.
	a.injectDiffMap()
	a.args.Tools.Freeze()

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Fix the underlying git error shown by the wrapped cause (check the ref names exist: git rev-parse <ref>)
  2. Run in a full clone (git fetch --unshallow) so the base commit is available
  3. Verify you are in a git repository and the diff mode flags (--from/--to/--commit) are valid
  4. Inspect the persisted session manifest for the RunFailureInput record

Example fix

// before (shallow clone in CI)
git clone --depth 1 repo && ocr review --from main
// after
git clone repo && git fetch origin main && ocr review --from origin/main
Defensive patterns

Strategy: try-catch

Validate before calling

git rev-parse --verify "$FROM_REF" && git rev-parse --verify "$TO_REF" || { echo "ref missing" >&2; exit 1; }
git rev-parse --is-inside-work-tree >/dev/null || exit 1

Try / catch

comments, err := agent.Run(ctx)
if err != nil {
    var loadErr error
    if errors.As(err, &loadErr) && strings.Contains(err.Error(), "load diffs:") {
        // inspect wrapped cause with errors.Unwrap / %v for the git error
        log.Fatalf("review input could not be loaded: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Agent.Run when loadDiffs fails — e.g. the configured base/ref produces no valid git diff, a git command error (bad ref, empty repo, detached state), or the diff source is unreadable. The wrapped cause (err) names the actual git/diff problem.

Common situations: Reviewing a PR branch that was force-pushed or deleted; running in a shallow clone missing the base commit; wrong --from/--to/--commit ref names; running outside a git repository.

Related errors


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/9cfceb943d0b839e. Report an issue: GitHub.