#16249: fix(sessions): allow cross-agent session paths in multi-agent bindings
stale
size: XS
Cluster:
Session Management Enhancements
## Summary
- Fix `resolvePathWithinSessionsDir` rejecting legitimate cross-agent session file paths when using multi-agent bindings
- Extend validation to accept absolute paths under any agent's `sessions/` directory within the same state root
- Add tests for cross-agent path acceptance and out-of-scope path rejection
## Problem
When a binding routes a message to a secondary agent, the gateway crashes with:
```
Session file path must be within sessions directory
```
**Root cause**: `resolvePathWithinSessionsDir` computes `path.relative(agentA/sessions, agentB/sessions/file)` → `../../agentB/sessions/file`. The `..` prefix triggers the security check, rejecting a perfectly valid cross-agent path.
This affects **all** multi-agent + binding setups across all platforms (Telegram, Discord, Slack, WhatsApp, etc.).
Related: #16211 (same root cause for WhatsApp DM session keys)
## Fix
When the existing containment check fails for an absolute path, verify whether the candidate falls under `<stateRoot>/agents/<agentId>/sessions/` — i.e. any agent's sessions directory within the same state root. This preserves the original security guarantee (no path traversal outside agent session directories) while allowing legitimate cross-agent routing.
## Test plan
- [x] Existing tests pass (13/13)
- [x] New test: accepts absolute paths in another agent's sessions dir (cross-agent binding)
- [x] New test: rejects `/etc/passwd` (completely outside state root)
- [x] New test: rejects paths to non-session agent subdirectories (`agents/work/config/secrets.json`)
- [x] Lint (`oxlint`) and format (`oxfmt`) pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes a critical bug where multi-agent bindings crashed with "Session file path must be within sessions directory" when routing messages between agents. The fix extends `resolvePathWithinSessionsDir` to accept absolute paths under any agent's sessions directory within the same state root (structure: `<stateRoot>/agents/<agentId>/sessions/`), preserving path traversal protection while enabling cross-agent routing.
**Key changes:**
- Modified `resolvePathWithinSessionsDir` (paths.ts:85-99) to validate cross-agent session paths by checking they follow the `agents/<agentId>/sessions/<file>` structure
- Added three new test cases covering cross-agent acceptance, out-of-bounds rejection (`/etc/passwd`), and non-session subdirectory rejection (`agents/work/config/secrets.json`)
- Updated existing test description to clarify it now tests cross-agent binding scenarios
**Security analysis:**
The validation logic correctly rejects path traversal attempts and paths outside agent session directories. However, when custom `sessionsDir` paths are used (via `storePath`), the state root calculation may produce unexpected results since it assumes the standard `<stateRoot>/agents/<agentId>/sessions` structure. This is a low-severity edge case for non-standard configurations.
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge with one edge-case consideration for non-standard configurations
- Score of 4 reflects a well-tested fix for a real production bug. The implementation correctly handles the standard use case (multi-agent bindings within default agent directories) with proper path validation. Test coverage includes both positive cases (cross-agent paths) and negative cases (path traversal attempts). The logic comment on state root calculation in non-standard configurations is a valid concern but represents an edge case that likely doesn't affect typical deployments. No critical security issues identified.
- Pay attention to `src/config/sessions/paths.ts:88-99` regarding the state root calculation with custom sessionsDir configurations
<sub>Last reviewed commit: 92ff0a0</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
#15176: fix(sessions): allow channel-routed session IDs and cross-agent paths
by cathrynlavery · 2026-02-13
87.3%
#15793: fix(sessions): gracefully handle stale cross-agent session file paths
by lxcong · 2026-02-13
86.2%
#16171: fix: trust absolute sessionFile paths in multi-agent setups [AI-ass...
by iJaack · 2026-02-14
85.7%
#15744: fix: allow cross-agent session path validation
by scottgl9 · 2026-02-13
84.8%
#15941: fix(sessions): allow session file paths from other agents' sessions...
by LiJianLi128 · 2026-02-14
81.6%
#16135: fix: handle session file paths from other agents in doctor command
by MisterGuy420 · 2026-02-14
81.3%
#20336: fix(sessions): resolve transcriptPath using agentId when storePath ...
by Limitless2023 · 2026-02-18
80.7%
#15982: fix: pass agentId to resolveSessionFilePath in reply flow (NX-003)
by automagik-genie · 2026-02-14
80.4%
#23656: fix(routing): trust binding agentId even when not in agents.list
by SleuthCo · 2026-02-22
80.3%
#15888: fix: store relative session file paths instead of absolute
by devAnon89 · 2026-02-14
80.2%