#20851: fix: harden resolveUserPath and compact against undefined workspaceDir
agents
size: XS
trusted-contributor
Cluster:
Bootstrap and Plugin Fixes
## Summary
- Guard `resolveUserPath()` against `undefined`/`null` input — previously crashed with `Cannot read properties of undefined (reading 'trim')`
- Update `compactEmbeddedPiSessionDirect()` to use `resolveRunWorkspaceDir()` instead of calling `resolveUserPath()` directly with a potentially undefined `params.workspaceDir`
## Root cause
Sub-agent compaction passes `params.workspaceDir` to `resolveUserPath()`, but `workspaceDir` can be `undefined` when the session was created without an explicit workspace. The `.trim()` call on line 241 of `utils.ts` crashes on `undefined`.
## Changes
- `src/utils.ts`: Early return `""` for falsy input in `resolveUserPath()`
- `src/agents/pi-embedded-runner/compact.ts`: Use `resolveRunWorkspaceDir()` for proper workspace resolution (consistent with `runEmbeddedAttempt`)
- `src/utils.test.ts`: Test covering `undefined` and `null` inputs
## Test plan
- [x] `pnpm build` passes
- [x] `pnpm test src/utils.test.ts` — 26 tests pass, including new undefined/null guard test
- [x] Rebased on latest `main`, no conflicts
---
_Re-opened from #12172 (auto-closed during fork maintenance)._
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixed a crash in `resolveUserPath()` when passed `undefined` or `null` values. The function previously crashed with "Cannot read properties of undefined (reading 'trim')" when `workspaceDir` was undefined during sub-agent compaction. The PR adds an early return for falsy inputs and updates `compactEmbeddedPiSessionDirect()` to use `resolveRunWorkspaceDir()` for proper workspace resolution with fallback handling, matching the pattern already used in `runEmbeddedAttempt()`. Includes test coverage for the undefined/null guard.
<h3>Confidence Score: 5/5</h3>
- Safe to merge with no risk - defensive fix with proper test coverage
- The changes are defensive programming improvements that prevent crashes. The fix in `resolveUserPath()` adds a simple guard against falsy inputs, and the update to use `resolveRunWorkspaceDir()` aligns with existing patterns in the codebase. Tests confirm the fix works correctly, and the changes make the code more robust without altering intended behavior.
- No files require special attention
<sub>Last reviewed commit: e7298f3</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#18647: fix(agents): guard against undefined paths in injectedFiles
by kleinpanic · 2026-02-16
82.0%
#12956: fix: guard .trim() calls on potentially undefined workspaceDir
by omair445 · 2026-02-10
80.1%
#22917: fix: Use agent's configured workspace when spawned as subagent
by jriff · 2026-02-21
79.5%
#18914: fix: use per-session workspaceDir instead of process.cwd() for post...
by irchelper · 2026-02-17
79.1%
#17757: fix(agents): resolve relative workspace paths against state dir, no...
by Phineas1500 · 2026-02-16
78.1%
#17445: fix(pi-embedded): add aggregate timeout to compaction retry + harde...
by joeykrug · 2026-02-15
77.4%
#22786: fix: guard against undefined file.path in system-prompt-report
by miloudbelarebia · 2026-02-21
77.1%
#7085: test: skip flaky workspace-paths & safe-bins tests on non-Linux/CI ...
by ThinkIbrokeIt · 2026-02-02
76.9%
#7569: fix: add null checks to prevent TypeError in subagent spawn
by kaigritun · 2026-02-03
76.8%
#18724: fix(compaction): add defensive guards for undefined session.messages
by mdlmarkham · 2026-02-17
76.5%