Skip to content

fix(share): pre-flight remote path before invoking sshfs (#3414)#3647

Merged
cv merged 2 commits into
NVIDIA:mainfrom
latenighthackathon:fix/share-mount-remote-path-preflight
May 16, 2026
Merged

fix(share): pre-flight remote path before invoking sshfs (#3414)#3647
cv merged 2 commits into
NVIDIA:mainfrom
latenighthackathon:fix/share-mount-remote-path-preflight

Conversation

@latenighthackathon

@latenighthackathon latenighthackathon commented May 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #3414. nemoclaw <sandbox> share mount exits non-zero with no stderr when the remote sandbox path does not exist (e.g. a typo). sshfs is silent in this case, so the CLI surfaced only the bare SSHFS mount failed. line and the user had no signal that the source path was the problem. Reported by @SeseMueller in #3235 as a follow-up to the writable-fs error fix.

Related Issue

Closes #3414

Changes

  • New checkSandboxPathExists dep on ShareCommandDeps (src/lib/share-command-deps.ts). Default impl runs openshell sandbox exec <name> -- test -e <remotePath> with the same OPENSHELL_PROBE_TIMEOUT_MS budget as the existing getSshConfig probe, and treats a zero exit status as "path exists" (everything else is missing or unreachable).
  • New exported helper assertSandboxPathExistsOrExit(deps, sandboxName, remotePath) in src/lib/share-command.ts. Consults the dep, emits a structured error when the probe returns non-zero, and exits 1. The error is phrased as a verification failure rather than a definitive "path is missing" claim, because the probe also returns false on transient exec failures (sandbox just restarted, gRPC hiccup), and a wrong-cause message wastes the user's time. Extracted so the behavior is testable without driving the full sshfs lifecycle.
  • runShareMount calls the helper after ensureLive and before getSshConfig, so a non-verifiable remote path fails fast with:
  Could not verify sandbox path '/sandbox/typo' in sandbox 'my-assistant' (missing path or probe failure).
  Verify the path with: nemoclaw my-assistant connect, then ls /sandbox/typo
  The default is /sandbox; check for typos in any custom path you passed.

No SSH config is written, no sshfs binary is invoked, no local mount directory is created when the pre-flight fails.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only

Verification

  • npx prek run --all-files passes for the staged files (includes the source-shape test budget gate).
  • Three behavior tests in test/share-command-remote-path.test.ts cover the happy path (no exit, no stderr), the missing-path exit (verifies error contents and that the dep was called with the right args), and the cliName branding hint (so the nemohermes alias surfaces nemohermes hermes connect rather than nemoclaw hermes connect).
  • npx vitest run test/share-command-remote-path.test.ts - 3/3 pass.
  • npx tsx scripts/find-source-shape-tests.ts - 0 source-shape cases (no source-text assertions).
  • npm run build:cli clean.
  • No secrets, API keys, or credentials committed.

Signed-off-by: latenighthackathon latenighthackathon@users.noreply.github.com

Summary by CodeRabbit

  • New Features

    • Added pre-flight validation for share mount to verify the remote path exists in the sandbox before attempting to connect.
  • Bug Fixes

    • Mount operations now fail early with helpful guidance if the remote path cannot be verified, preventing connection attempts with invalid paths.

Review Change Stack

Closes NVIDIA#3414. `nemoclaw <sandbox> share mount /missing/path` invokes
`sshfs` directly without first checking that the remote path exists
inside the sandbox. `sshfs` exits non-zero with empty stderr on a
missing remote path, and the existing "SSHFS mount failed." line that
`runShareMount` emits leaves the user with no actionable error.

Add a `checkSandboxPathExists()` dep that calls
`openshell sandbox exec <name> -- test -e <remotePath>` with a bounded
probe timeout and returns a boolean. `runShareMount` calls it after the
sandbox-live check (so we know exec is reachable) but before the
filesystem-writability check (so we can avoid creating an empty mount
directory when the source path is missing). On failure the user sees a
three-line message naming the missing path, explaining the exec probe
either could not run or returned non-zero, and pointing at
`openshell sandbox exec ls <parent>` as a follow-up.

Tests: `test/share-command-remote-path.test.ts` covers 6 paths: the
preflight passing for an existing path, exit on missing path, exit on
exec timeout, exit on exec error, mkdir cleanup on missing path, and
ordering after `ensureLive`. 6/6 pass; existing 6/6 share-command.test.ts
pass unchanged after wiring `checkSandboxPathExists` into the test
ShareCommandDeps factory.

Signed-off-by: latenighthackathon <support@latenighthackathon.com>
Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
@copy-pr-bot

copy-pr-bot Bot commented May 16, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented May 16, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: fad1b366-5a07-47d8-98ec-93bbb0337b85

📥 Commits

Reviewing files that changed from the base of the PR and between a8dff7a and 2acdad4.

📒 Files selected for processing (4)
  • src/lib/share-command-deps.ts
  • src/lib/share-command.test.ts
  • src/lib/share-command.ts
  • test/share-command-remote-path.test.ts

📝 Walkthrough

Walkthrough

This PR implements a pre-flight check for the remote sandbox path before invoking sshfs in the share mount command. A new checkSandboxPathExists dependency probes the path and early-exits with user guidance if verification fails, preventing silent sshfs failures on typo'd or missing remote paths.

Changes

Pre-flight Path Existence Check

Layer / File(s) Summary
Path existence check dependency
src/lib/share-command-deps.ts, src/lib/share-command.test.ts
ShareCommandDeps gains checkSandboxPathExists(sandboxName, remotePath): boolean, wired in buildShareCommandDeps() by running openshell sandbox exec ... test -e <remotePath> with ignoreError: true and returning status === 0. Test makeDeps supplies a default true mock.
Pre-flight assertion and mount integration
src/lib/share-command.ts
New exported assertSandboxPathExistsOrExit() calls the dependency and exits with multi-line error guidance on failure. Integrated into runShareMount as an early check after sandbox liveness and before SSH config, aborting the flow when the remote source path cannot be verified.
Remote path assertion coverage
test/share-command-remote-path.test.ts
Vitest suite for assertSandboxPathExistsOrExit verifying success (no exit), failure (exit code 1, specific error messages, CLI name substitution), and correct argument passing to the dependency.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A path check hops ahead with care,
Before the mount attempt goes there,
If the remote path cannot be found,
Clear guidance helps—no silent sound!
The typo's caught before it's far. 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: adding a pre-flight check for the remote sandbox path before invoking sshfs in the share mount flow, directly addressing issue #3414.
Linked Issues check ✅ Passed The pull request fully implements the objectives from #3414: adds checkSandboxPathExists dependency, implements assertSandboxPathExistsOrExit with structured error messaging, integrates pre-flight check into runShareMount before sshfs invocation, and includes comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing the pre-flight remote path verification feature from #3414; no unrelated modifications detected across dependency wiring, helper functions, integration points, and test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Comment @coderabbitai help to get the list of available commands and usage tips.

@cv cv merged commit 17965a7 into NVIDIA:main May 16, 2026
17 checks passed
@latenighthackathon latenighthackathon deleted the fix/share-mount-remote-path-preflight branch May 17, 2026 06:13
ericksoa pushed a commit that referenced this pull request May 18, 2026
## Summary
Updates the NemoClaw documentation for the v0.0.45 release by
summarizing the user-facing changes merged since v0.0.44 and bumping the
docs version metadata.
Refreshes generated user skills so agent-facing references match the
source docs.

## Changes
- Added v0.0.45 release notes covering onboarding recovery, local
inference, channel cleanup, share mount diagnostics, uninstall cleanup,
and security redaction updates.
- Updated command and troubleshooting docs for sandbox name limits, GPU
gateway reuse, DNS preflight behavior, channel removal cleanup, and
share mount path validation.
- Bumped docs version metadata to 0.0.45 and regenerated NemoClaw user
skills from the docs.
- Source summary: #3672 -> `docs/reference/commands.md`: documented
channel removal detaching bridge providers and un-applying channel
policy presets.
- Source summary: #3678 -> `docs/about/release-notes.md`: documented
Ollama streamed usage accounting in the release notes.
- Source summary: #3670 -> `docs/reference/commands.md`,
`docs/reference/troubleshooting.md`: documented safe GPU gateway
replacement behavior.
- Source summary: #3664 -> `docs/about/release-notes.md`: documented
blueprint permission normalization in the release notes.
- Source summary: #3181 -> `docs/reference/troubleshooting.md`:
documented GPU toolkit guidance when host drivers work but passthrough
is disabled.
- Source summary: #3554 -> `docs/about/release-notes.md`: documented
host `openshell-gateway` cleanup during uninstall.
- Source summary: #3651 -> `docs/reference/troubleshooting.md`:
documented the uncached `.invalid` DNS preflight probe.
- Source summary: #3643 -> `docs/reference/commands.md`: included
existing `NEMOCLAW_PROVIDER` interactive-mode behavior in generated
docs.
- Source summary: #3647 -> `docs/reference/commands.md`: documented
remote sandbox path verification for `share mount`.
- Source summary: #3646 -> `docs/reference/commands.md`: included
existing local writable mount target guidance in generated docs.
- Source summary: #3642 -> `docs/inference/use-local-inference.md`,
`docs/reference/commands.md`: documented managed-vLLM model override and
gated-model token checks.
- Source summary: #3639 -> `docs/reference/commands.md`: documented the
63-character sandbox name limit.

## Type of Change
- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [x] Doc only (includes code sample changes)

## Verification
- [ ] `npx prek run --all-files` passes
- [ ] `npm test` passes
- [ ] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed
- [x] Docs updated for user-facing behavior changes
- [x] `make docs` builds without warnings (doc changes only)
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

Commit hooks passed for the staged files. A standalone `npx prek run
--all-files` attempt was blocked by sandbox access to
`/Users/miyoungc/.cache/prek/prek.log`, so that checkbox is left
unchecked.

---
<!-- DCO sign-off required by CI. Run: git config user.name && git
config user.email -->
Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Enhanced CLI command reference documentation with clearer guidance on
onboarding, GPU passthrough, inference configuration, channel removal,
and shared mounts.
* Improved troubleshooting sections with better DNS resolution and GPU
passthrough remediation steps.
  * Added documentation for overriding managed vLLM model selection.
* Updated release notes for v0.0.45 reflecting infrastructure and
workflow improvements.

* **Version Bump**
  * Released v0.0.45.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/NVIDIA/NemoClaw/pull/3755?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@wscurran wscurran added the bug-fix PR fixes a bug or regression label Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug-fix PR fixes a bug or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

share mount: surface a clear error when the remote sandbox path does not exist

3 participants