← Back to PRs

#18593: fix: resolve symlinks in session path validation (#18553)

by EpaL open 2026-02-16 21:47 View on GitHub →
stale size: XS
## Problem When the OpenClaw state directory is accessed through a symlink (e.g. `~/.clawdbot -> ~/.openclaw` after the rename migration), session file paths stored with the old symlink prefix fail the containment check in `resolvePathWithinSessionsDir`. `path.relative()` does not follow symlinks, so a stored path like: ``` /Users/foo/.clawdbot/agents/main/sessions/abc.jsonl ``` computed relative to: ``` /Users/foo/.openclaw/agents/main/sessions/ ``` produces `../../../../.clawdbot/agents/main/sessions/abc.jsonl` (starts with `..`), which fails validation even though both paths resolve to the same physical file. ### Impact - `doctor --fix` crashes after applying config migrations - **Discord guild message handler crashes on every inbound message** — bots can send to channels but cannot receive - Any code path that resolves stored `sessionFile` paths fails ### Root cause The `.clawdbot` → `.openclaw` migration left a compatibility symlink, but `resolvePathWithinSessionsDir` and `resolvePathFromAgentSessionsDir` use `path.resolve()` which does not follow symlinks. ## Fix Use `fs.realpathSync()` to resolve symlinks on both the base sessions directory and the candidate path before computing the relative path. A new `safeRealpathSync()` helper falls back gracefully if the path does not exist yet. ## Testing - Verified on a real system with `.clawdbot -> .openclaw` symlink - 6 stale session entries with old paths now resolve correctly - Discord guild message handler no longer crashes - `doctor --fix` completes without error Fixes #18553 <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR fixes session path validation failures caused by symlinks (e.g., `~/.clawdbot → ~/.openclaw`) by using `fs.realpathSync` to resolve symlinks on both the base directory and candidate paths before computing relative paths. A new `safeRealpathSync` helper gracefully falls back when paths don't exist yet. The fix is applied consistently in both `resolvePathFromAgentSessionsDir` and `resolvePathWithinSessionsDir`. - The symlink fix itself is well-implemented: resolving both sides of the comparison before calling `path.relative()` is the correct approach. - **Potential regression**: The PR removes a structural fallback (`return path.resolve(trimmed)`) that was explicitly added in commit `90774c09` to handle a *different* scenario — when `OPENCLAW_STATE_DIR` changes between session creation and resolution (no symlinks involved). This could re-introduce the issues fixed by that earlier commit (#15410, #15565, #15468). <h3>Confidence Score: 3/5</h3> - The symlink fix is correct but an unrelated structural fallback was removed, which may re-introduce a previously fixed regression. - The core fix (resolving symlinks via realpathSync) is sound and addresses the stated problem. However, the removal of the structural fallback for OPENCLAW_STATE_DIR changes is a potential regression that could affect users in multi-agent setups where the state directory path changes. This lowers confidence from what would otherwise be a 4. - Pay close attention to `src/config/sessions/paths.ts` — specifically the removed structural fallback in `resolvePathWithinSessionsDir` around lines 164-170. <sub>Last reviewed commit: fc68137</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