#16061: fix(sessions): tolerate invalid sessionFile metadata
stale
size: XS
Cluster:
Session Management Enhancements
fix(sessions): tolerate invalid sessionFile metadata
AI-assisted: yes (Codex/OpenClaw agent).
Problem
- Some deployments end up with `sessions.json` entries containing a `sessionFile` field that is stale/corrupted
(e.g., absolute paths persisted historically, state dir migrations, or other bad metadata).
- `resolveSessionFilePath()` currently treats an invalid `sessionFile` as fatal and throws:
"Session file path must be within sessions directory".
- When this happens inside chat/channel handlers (observed with Telegram), the handler can fail mid-update,
leading to silent non-replies even though the message was received.
Fix
- Treat `entry.sessionFile` as optional, best-effort metadata.
- If validation fails, ignore it and fall back to the derived safe transcript path based on `sessionId`
(which is already validated and resolved within the agent sessions directory).
Security
- Containment checks are still enforced when a candidate is provided.
- This change does NOT allow escaping paths; it simply avoids taking down message handling due to invalid metadata.
Testing
- Local (Istanbul VM):
- `pnpm format:check` PASS
- `pnpm check` PASS
- `pnpm vitest run src/config/sessions/paths.test.ts` PASS
Concise output:
- "✓ src/config/sessions/paths.test.ts (12 tests)"
- Real-world repro:
- Reproduced intermittent Telegram handler failures caused by invalid/stale `sessionFile` metadata, and confirmed this
change prevents silent non-replies by falling back to the derived safe transcript path.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR makes `resolveSessionFilePath` resilient to corrupted or stale `sessionFile` metadata in `sessions.json`. Instead of throwing (which could crash message handlers mid-update, causing silent non-replies on Telegram and other channels), invalid candidates now fall back to the derived safe transcript path based on `sessionId`.
- `resolveSessionFilePath` in `paths.ts` now wraps `resolvePathWithinSessionsDir` in a try/catch; if the persisted `sessionFile` fails validation (path traversal, absolute path outside sessions dir, etc.), it silently falls back to `{sessionId}.jsonl`
- Security containment checks are still enforced — the change does not allow path escapes, it just avoids a fatal error on bad metadata
- Tests updated from expecting throws to verifying fallback behavior, while still validating that legitimate candidates within the sessions dir are accepted
- Multiple callers (e.g., `get-reply-run.ts`, `agent-runner.ts`, `doctor-state-integrity.ts`) don't have their own try/catch around this function, confirming the fix is necessary at the source
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge — it strictly improves resilience without weakening any security checks.
- The change is minimal and well-scoped: a single try/catch in `resolveSessionFilePath` with a safe fallback. Security containment checks remain enforced for valid candidates. The fallback path is derived from `sessionId` which is validated by `validateSessionId` (alphanumeric + `._-` only). Tests cover all key scenarios. No new dependencies or architectural changes.
- No files require special attention.
<sub>Last reviewed commit: c06f155</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#15793: fix(sessions): gracefully handle stale cross-agent session file paths
by lxcong · 2026-02-13
87.1%
#15888: fix: store relative session file paths instead of absolute
by devAnon89 · 2026-02-14
87.0%
#15744: fix: allow cross-agent session path validation
by scottgl9 · 2026-02-13
86.4%
#15684: fix(telegram): persist relative session transcript paths
by Jdo300 · 2026-02-13
85.9%
#17132: fix: filter out invalid session entries with empty sessionFile
by Limitless2023 · 2026-02-15
85.7%
#3410: fix(sessions): always compute session paths from current environment
by sakunsylvi · 2026-01-28
85.5%
#15176: fix(sessions): allow channel-routed session IDs and cross-agent paths
by cathrynlavery · 2026-02-13
84.6%
#20336: fix(sessions): resolve transcriptPath using agentId when storePath ...
by Limitless2023 · 2026-02-18
83.9%
#4664: fix: per-session metadata files to eliminate lock contention
by tsukhani · 2026-01-30
83.8%
#20188: fix: Update sessionFile path when rolling to new session in cron jobs
by jriff · 2026-02-18
82.7%