#23583: fix(agents): catch session JSONL write failures instead of crashing
agents
size: XS
Cluster:
Session Lock Improvements
## Summary
- Fixes a hard crash when session JSONL file becomes temporarily unwritable (e.g., transient EACCES errors from virtiofs under Colima)
- Introduces `safeAppend` helper that wraps `originalAppend` in try/catch
- On failure, logs the error and gracefully drops the message instead of crashing the gateway
## Problem
When the session JSONL file becomes temporarily unwritable, any call to `originalAppend` in `session-tool-result-guard.ts` throws synchronously. Because the error is uncaught at the call sites, it propagates up and crashes the gateway process with `exit(1)`.
This is a hard crash for what is ultimately a non-fatal I/O condition: the session history log failed to persist one message, but the active agent conversation can continue.
## Solution
Introduced a `safeAppend` helper that wraps `originalAppend` in a try/catch. All three call sites in `installSessionToolResultGuard` are updated to use it:
- `flushPendingToolResults` (flush path)
- the `persisted` path in the main interception handler
- the `finalMessage` path in the main interception handler
On failure, logs: `[session-guard] session write failed (<reason>); message dropped (file: <path>)`
Fixes #23556
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Wraps session JSONL writes in try/catch to prevent gateway crashes from transient I/O errors (e.g., EACCES under virtiofs). Introduces `safeAppend` helper that logs errors and gracefully drops messages instead of crashing.
- Prevents hard crashes when session file becomes temporarily unwritable
- All three `originalAppend` call sites now use `safeAppend` wrapper
- Logs dropped messages with file path and error reason for debugging
- Minor optimization: moves `sessionFile` lookup outside the append handler to avoid repeated calls
<h3>Confidence Score: 5/5</h3>
- Safe to merge with minimal risk - straightforward defensive error handling that prevents crashes
- The change is well-scoped and implements a simple try/catch wrapper around I/O operations. The logic correctly handles errors by logging and returning undefined, which matches the existing return type contract. All three call sites are consistently updated. The only minor consideration is that the sessionFile path is captured at installation time rather than dynamically, but this doesn't affect correctness for the common case
- No files require special attention
<sub>Last reviewed commit: 9f9060f</sub>
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#23557: fix: catch session JSONL write failures instead of crashing
by Joe3112 · 2026-02-22
93.4%
#21828: fix: acquire session write lock in delivery mirror and gateway chat...
by inkolin · 2026-02-20
80.8%
#20431: fix(sessions): add session contamination guards and self-leak lock ...
by marcomarandiz · 2026-02-18
79.5%
#17132: fix: filter out invalid session entries with empty sessionFile
by Limitless2023 · 2026-02-15
78.3%
#16061: fix(sessions): tolerate invalid sessionFile metadata
by haoyifan · 2026-02-14
78.2%
#3647: fix: sanitize tool arguments in session history
by nhangen · 2026-01-29
78.0%
#15050: fix: transcript corruption resilience — strip aborted tool_use bloc...
by yashchitneni · 2026-02-12
77.8%
#3622: fix(agents): drop orphan tool results
by mickobizzle · 2026-01-28
77.2%
#9011: fix(session): auto-recovery for corrupted tool responses [AI-assisted]
by cheenu1092-oss · 2026-02-04
76.9%
#12296: security: persistence-only secret redaction for session transcripts
by akoscz · 2026-02-09
76.9%