alibaba/open-code-review · error

finalize session: %w

Error message

finalize session: %w

What it means

In the same failure path of Agent.Run (internal/agent/agent.go), if a.session.Finalize() fails while persisting the failed session_end after a diff-load failure, the persistence error is wrapped as 'finalize session: %w' and joined with the 'load diffs' error via errors.Join, so both causes are reported instead of one silently masking the other.

Source

Thrown at internal/agent/agent.go:301

	// 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()

	totalChanged := len(a.diffs)
	reviewCount := a.countReviewable(a.diffs)

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Check disk space and write permissions on the session/state directory
  2. Clear stale or corrupted session files for this run's session ID
  3. Avoid concurrent runs sharing one session directory
  4. After fixing persistence, also fix the underlying load-diffs cause (both are joined in the error)

Example fix

// before (read-only state dir in CI)
OCR_STATE_DIR=/ro/state ocr review
// after
OCR_STATE_DIR=/writable/state ocr review
Defensive patterns

Strategy: try-catch

Validate before calling

test -w "$OCR_STATE_DIR" || { echo "state dir not writable: $OCR_STATE_DIR" >&2; exit 1; }
df -h "$OCR_STATE_DIR" | awk 'NR==2 {exit ($5+0 > 95 ? 1 : 0)}' || { echo "state dir nearly full" >&2; exit 1; }

Try / catch

comments, err := agent.Run(ctx)
if err != nil {
    if strings.Contains(err.Error(), "finalize session:") {
        // persistence failure joined with the primary cause; check disk/permissions
        log.Printf("session persistence failed (disk/permissions?): %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Agent.Run hits a loadDiffs error AND the session persistence layer fails during Finalize — typically a filesystem error writing the session JSONL/manifest (disk full, permissions, read-only mount, corrupted session directory).

Common situations: CI containers with small or read-only tmp dirs; concurrent runs writing the same session directory; disk quota exhaustion; permission changes on the state directory between runs.

Related errors


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