fix(fs): validate mount paths with POSIX semantics on Windows#1492
Merged
fix(fs): validate mount paths with POSIX semantics on Windows#1492
Conversation
`MountableFs::mount` previously called `Path::is_absolute`, which on
Windows requires a drive prefix (`C:\…`) and rejects POSIX-style paths
like `/workspace`. Bashkit's VFS is always POSIX-style on every host,
so the platform-aware predicate broke `bash.mount("/workspace", fs)`
on Windows — surfacing as the publish-only test failure
`vfs > filesystem external roundtrip mounts into bash` after the
interop FS feature shipped in 0.2.0.
Switch to `Path::has_root`, which returns true for any leading `/`
on both Unix and Windows. Move the validation ahead of normalization
so the caller's intent (absolute vs. relative) is checked against
the original input rather than the always-rooted normalized form.
Also extract the check into a small `is_posix_absolute` helper so the
behavior is unit-testable without spinning up a full filesystem.
Tests:
- new helper-level tests cover absolute vs. relative paths and the
edge cases (`/`, empty, `./foo`)
- new integration test asserts `mount("/workspace", ...)` succeeds on
the local host (proves Linux behavior is unchanged) and documents
the regression
- new integration test asserts relative paths are still rejected with
an error containing `absolute`
PR CI is Linux-only for Rust, so this fix is verified on Windows by
the JS publish workflow's full-matrix `vfs.spec.ts` run.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
bashkit | 5d62f52 | Commit Preview URL Branch Preview URL |
Apr 30 2026, 04:13 PM |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
chaliy
added a commit
that referenced
this pull request
Apr 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MountableFs::mountvalidated paths withPath::is_absolute, which on Windows requires a drive prefix (C:\…) and rejects POSIX-style absolute paths like/workspace. Bashkit's VFS is always POSIX-style on every host, so this brokebash.mount("/workspace", fs)on Windows.This surfaced after the v0.2.0 release as the publish-only test failure:
The interop FS feature in #1353 exercised
mount()from JS for the first time, and the JS publish workflow runs the full Windows × Node 20/22/24 matrix that PR CI doesn't.Why this regressed silently
PR CI runs Rust tests on
ubuntu-latestonly. Windows coverage exists exclusively inpublish-js.yml, which only runs onrelease: published. So the bug rode all the way to the v0.2.0 GitHub Release before it was observed.Fix
Path::has_rootinstead ofPath::is_absolute.has_rootreturns true for any leading/on both Unix and Windows.normalize_pathalways returns a rooted path, which would have masked the check entirely had we left it after.is_posix_absolutehelper so the platform-portability invariant is unit-testable in isolation.Test coverage
Added in
crates/bashkit/src/fs/mountable.rs:test_is_posix_absolute_accepts_root_paths—/,/workspace,/data/subtest_is_posix_absolute_rejects_relative_paths—relative,relative/path,./foo,""test_mount_accepts_posix_absolute_path_on_any_host— regression test assertingmount("/workspace", …)andmount("/data/sub", …)succeed (post-fix this passes on Windows; pre-fix it would fail there)test_mount_rejects_relative_path— error path still rejects relative inputs with anabsolutemessagePR CI verifies the Linux behavior is unchanged. Windows behavior will be verified by the JS publish workflow's
vfs.spec.tsonce v0.2.1 is cut (or by re-dispatchingpublish-js.ymlagainstv0.2.0after this lands on main).Test plan
cargo fmt --checkcargo clippy --workspace --all-targets -- -D warningscargo test --workspace(84 suites green)publish-js.ymlfor v0.2.0 and confirm Windows tests pass + npm publishesGenerated by Claude Code