← Back to PRs

#17815: fix: use $HOME as cwd for global update to prevent path-dedot panic

by frankekn open 2026-02-16 06:23 View on GitHub →
app: macos cli commands size: S
## Summary Fixes #7135. During `openclaw update` for global npm/pnpm/bun installs, the update step's `cwd` was set to the package install directory (`pkgRoot`). When `npm i -g` replaces that directory, any post-install hooks (e.g. `mise reshim`) find their working directory has vanished, causing `path-dedot` to panic on `unwrap()` of `std::env::current_dir()`. ## Approach Instead of patching each call site individually, this PR introduces `globalInstallConfig()` in `update-global.ts` — a centralised helper that returns both `argv` and a safe `cwd` (`os.homedir()`). The `-g` flag already determines the install target via the package manager's global prefix config, so the child process `cwd` is irrelevant to where packages are installed. Encapsulating this in one place ensures future call sites automatically get a stable `cwd` without needing to know about this edge case. ## Changes | File | Change | |------|--------| | `src/infra/update-global.ts` | Added `globalInstallConfig()` that returns `{ argv, cwd: os.homedir() }` | | `src/infra/update-runner.ts` | Switched from `globalInstallArgs()` + `cwd: pkgRoot` to `globalInstallConfig()` | | `src/cli/update-cli/update-command.ts` | Switched both global update and global install call sites to `globalInstallConfig()` | | `src/infra/update-runner.test.ts` | Added regression test asserting the global update step runs with `$HOME` as cwd, not the install directory | ## Test plan - [x] Existing `update-runner.test.ts` tests pass (14/14) - [x] New regression test verifies cwd is `os.homedir()`, not `pkgRoot` - [x] `pnpm lint` passes (0 errors) - [x] `pnpm build` passes <!-- greptile_comment --> <h3>Greptile Summary</h3> Fixes a `path-dedot` panic during `openclaw update` for global npm/pnpm/bun installs by changing the child process `cwd` from the package install directory (`pkgRoot`) to `$HOME`. The package install directory can be deleted and recreated by `npm i -g` during the update, which causes post-install hooks (e.g. `mise reshim`) to fail when they call `std::env::current_dir()` on a non-existent path. - Introduced `globalInstallConfig()` in `src/infra/update-global.ts` that bundles both `argv` and a safe `cwd` (`os.homedir()`) into a single return value, replacing direct calls to `globalInstallArgs()` + manual `cwd` at each call site - Updated all three global install call sites (`update-runner.ts`, two in `update-command.ts`) to use the new helper - Added a regression test asserting the global update command runs with `os.homedir()` as cwd, not the install directory <h3>Confidence Score: 5/5</h3> - This PR is safe to merge — it's a targeted, well-tested bug fix with no behavioral side effects. - The change is minimal and focused: it replaces an unsafe `cwd` (the package install directory that can vanish mid-update) with `os.homedir()`, which is always stable. The `-g` flag makes the actual install target independent of cwd, so this change has no effect on where packages are installed. All three call sites are updated consistently, a regression test is added, and the PR description clearly explains the root cause. No new dependencies, no architectural changes, no risk of regressions. - No files require special attention <sub>Last reviewed commit: 20e5c37</sub> <!-- greptile_other_comments_section --> <sub>(4/5) You can add custom instructions or style guidelines for the agent [here](https://app.greptile.com/review/github)!</sub> <!-- /greptile_comment -->

Most Similar PRs