{"record":{"id":"138c3352c4cf8a36","repo":"alibaba/open-code-review","slug":"finalize-session-w","errorCode":null,"errorMessage":"finalize session: %w","messagePattern":"finalize session: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/agent.go","lineNumber":301,"sourceCode":"\n\t// Step 1: Parse diffs\n\tctx, diffSpan := telemetry.StartSpan(ctx, \"diff.parse\")\n\tif err := a.loadDiffs(ctx); err != nil {\n\t\tdiffSpan.End()\n\t\t// The builder already exists (agent.New created session + manifest), but\n\t\t// no item was selected yet. Record the run-level input failure at this\n\t\t// trigger point, then finalize and persist so the run still emits a\n\t\t// session_end with a failed manifest instead of looking aborted.\n\t\tif b := a.session.Manifest(); b != nil {\n\t\t\t_ = b.SetRunFailure(session.RunFailureInput, \"failed to resolve review input\")\n\t\t}\n\t\tmanifestErr := a.finalizeManifest()\n\t\t// Keep the load failure as the primary cause, but never drop a persistence\n\t\t// failure: a run that could not even write its failed session_end must\n\t\t// report both rather than silently prefer one.\n\t\tloadErr := fmt.Errorf(\"load diffs: %w\", err)\n\t\tif ferr := a.session.Finalize(); ferr != nil {\n\t\t\tmanifestErr = errors.Join(manifestErr, fmt.Errorf(\"finalize session: %w\", ferr))\n\t\t}\n\t\tif manifestErr != nil {\n\t\t\treturn nil, errors.Join(loadErr, manifestErr)\n\t\t}\n\t\treturn nil, loadErr\n\t}\n\ttelemetry.SetAttr(diffSpan, \"files.changed\", len(a.diffs))\n\ttelemetry.SetAttr(diffSpan, \"lines.inserted\", int64(a.totalInsertions))\n\ttelemetry.SetAttr(diffSpan, \"lines.deleted\", int64(a.totalDeletions))\n\tdiffSpan.End()\n\n\t// Build the read-only DiffMap from ALL parsed diffs (before filtering)\n\t// so the LLM can query diffs of related but filtered-out files.\n\ta.injectDiffMap()\n\ta.args.Tools.Freeze()\n\n\ttotalChanged := len(a.diffs)\n\treviewCount := a.countReviewable(a.diffs)","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/agent/agent.go#L283-L319","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Check disk space and write permissions on the session/state directory","Clear stale or corrupted session files for this run's session ID","Avoid concurrent runs sharing one session directory","After fixing persistence, also fix the underlying load-diffs cause (both are joined in the error)"],"exampleFix":"// before (read-only state dir in CI)\nOCR_STATE_DIR=/ro/state ocr review\n// after\nOCR_STATE_DIR=/writable/state ocr review","handlingStrategy":"try-catch","validationCode":"test -w \"$OCR_STATE_DIR\" || { echo \"state dir not writable: $OCR_STATE_DIR\" >&2; exit 1; }\ndf -h \"$OCR_STATE_DIR\" | awk 'NR==2 {exit ($5+0 > 95 ? 1 : 0)}' || { echo \"state dir nearly full\" >&2; exit 1; }","typeGuard":null,"tryCatchPattern":"comments, err := agent.Run(ctx)\nif err != nil {\n    if strings.Contains(err.Error(), \"finalize session:\") {\n        // persistence failure joined with the primary cause; check disk/permissions\n        log.Printf(\"session persistence failed (disk/permissions?): %v\", err)\n    }\n    return err\n}","preventionTips":["Ensure the state/session directory is writable and has free space","Do not run concurrent ocr processes against the same session directory","Monitor disk usage on CI runners that persist session state","Treat the joined error as two problems: fix both the load cause and the persistence cause"],"tags":["session","persistence","filesystem","agent"],"backgroundTag":"session-finalize-failure","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}