fix(onboard): validate custom Dockerfile path before onboarding#2597
Conversation
📝 WalkthroughWalkthroughAdds early validation of the Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI
participant Parser
participant FS
participant Onboard
User->>CLI: nemoclaw onboard --from <path>
CLI->>Parser: parseOnboardArgs(...)
Parser->>FS: path.resolve(<path>) / existsSync(<resolved>)
alt file exists
Parser->>Onboard: runOnboard(...)
Onboard->>Onboard: perform onboarding steps (gateway, provider, etc.)
Onboard-->>User: progress / success
else file missing
Parser-->>User: print error "Custom Dockerfile not found: <resolved>"
Parser->>CLI: process.exit(1)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Review rate limit: 9/10 reviews remaining, refill in 6 minutes. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/lib/onboard-command.test.ts (1)
117-120: Clean up temp artifacts created by tests.Both tests create temp directories/files but never remove them. Please add
try/finallycleanup (fs.rmSync(..., { recursive: true, force: true })) to avoid filesystem residue across repeated runs.Also applies to: 203-204
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/onboard-command.test.ts` around lines 117 - 120, Wrap the temp-dir creation and file writes in the tests that use tmpDir and dockerfilePath inside a try/finally so the temp artifacts are always removed; in the finally call fs.rmSync(tmpDir, { recursive: true, force: true }) (and similarly for the other test at the region around lines 203-204 referencing its temp dir) to ensure cleanup even on failures, keeping the tmpDir and dockerfilePath variable names to locate where to insert the try/finally blocks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/onboard-command.ts`:
- Around line 74-77: The current check only verifies existence of
requestedFromDockerfile (resolvedFromDockerfile) but allows directories; update
the validation in the onboard command so after resolving requestedFromDockerfile
you verify it's a regular file (e.g., using fs.statSync or fs.lstatSync and
stat.isFile()) and if not a file call error(` --from path not found:
${resolvedFromDockerfile}`) and exit(1) (same failure path as before); locate
the logic around resolvedFromDockerfile / requestedFromDockerfile in
onboard-command.ts to implement this extra isFile check.
---
Nitpick comments:
In `@src/lib/onboard-command.test.ts`:
- Around line 117-120: Wrap the temp-dir creation and file writes in the tests
that use tmpDir and dockerfilePath inside a try/finally so the temp artifacts
are always removed; in the finally call fs.rmSync(tmpDir, { recursive: true,
force: true }) (and similarly for the other test at the region around lines
203-204 referencing its temp dir) to ensure cleanup even on failures, keeping
the tmpDir and dockerfilePath variable names to locate where to insert the
try/finally blocks.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 8aac8018-a60b-4c0e-8e2f-2543fe7b7253
📒 Files selected for processing (2)
src/lib/onboard-command.test.tssrc/lib/onboard-command.ts
| const resolvedFromDockerfile = path.resolve(requestedFromDockerfile); | ||
| if (!fs.existsSync(resolvedFromDockerfile)) { | ||
| error(` --from path not found: ${resolvedFromDockerfile}`); | ||
| exit(1); |
There was a problem hiding this comment.
Reject non-file --from paths during parsing.
Current validation only checks path existence, so directories can pass and still fail later during onboarding. That weakens the fast-fail guarantee for invalid Dockerfile inputs.
Suggested fix
- if (!fs.existsSync(resolvedFromDockerfile)) {
+ if (!fs.existsSync(resolvedFromDockerfile) || !fs.statSync(resolvedFromDockerfile).isFile()) {
error(` --from path not found: ${resolvedFromDockerfile}`);
exit(1);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const resolvedFromDockerfile = path.resolve(requestedFromDockerfile); | |
| if (!fs.existsSync(resolvedFromDockerfile)) { | |
| error(` --from path not found: ${resolvedFromDockerfile}`); | |
| exit(1); | |
| const resolvedFromDockerfile = path.resolve(requestedFromDockerfile); | |
| if (!fs.existsSync(resolvedFromDockerfile) || !fs.statSync(resolvedFromDockerfile).isFile()) { | |
| error(` --from path not found: ${resolvedFromDockerfile}`); | |
| exit(1); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/onboard-command.ts` around lines 74 - 77, The current check only
verifies existence of requestedFromDockerfile (resolvedFromDockerfile) but
allows directories; update the validation in the onboard command so after
resolving requestedFromDockerfile you verify it's a regular file (e.g., using
fs.statSync or fs.lstatSync and stat.isFile()) and if not a file call error(`
--from path not found: ${resolvedFromDockerfile}`) and exit(1) (same failure
path as before); locate the logic around resolvedFromDockerfile /
requestedFromDockerfile in onboard-command.ts to implement this extra isFile
check.
3437db0 to
a9ee1bc
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/lib/onboard-command.ts (1)
75-79:⚠️ Potential issue | 🟠 MajorReject non-file
--frompaths during parsing.
existsSyncstill lets directories through, so a bad--fromcan make it past parsing and fail later in onboarding. Please also requireresolvedFromDockerfileto be a regular file before exiting early.Suggested fix
- if (!fs.existsSync(resolvedFromDockerfile)) { + if (!fs.existsSync(resolvedFromDockerfile) || !fs.statSync(resolvedFromDockerfile).isFile()) { error(` --from path not found: ${resolvedFromDockerfile}`); exit(1); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/onboard-command.ts` around lines 75 - 79, The check using fs.existsSync allows directories; update the validation for resolvedFromDockerfile (constructed via path.resolve(requestedFromDockerfile)) to ensure it exists and is a regular file before proceeding: after resolving, replace or augment the existsSync check with a file stat (e.g., fs.statSync or fs.lstatSync) and call .isFile() to verify it is a file, and if not call error(` --from path not found: ${resolvedFromDockerfile}`) followed by exit(1); keep the same error message and use the same symbols (resolvedFromDockerfile, error, exit) so the early exit happens at parse time.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/lib/onboard-command.ts`:
- Around line 75-79: The check using fs.existsSync allows directories; update
the validation for resolvedFromDockerfile (constructed via
path.resolve(requestedFromDockerfile)) to ensure it exists and is a regular file
before proceeding: after resolving, replace or augment the existsSync check with
a file stat (e.g., fs.statSync or fs.lstatSync) and call .isFile() to verify it
is a file, and if not call error(` --from path not found:
${resolvedFromDockerfile}`) followed by exit(1); keep the same error message and
use the same symbols (resolvedFromDockerfile, error, exit) so the early exit
happens at parse time.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 454eb415-bf43-46c9-b632-6ee240ae2458
📒 Files selected for processing (2)
src/lib/onboard-command.test.tssrc/lib/onboard-command.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/lib/onboard-command.test.ts
Reject missing --from Dockerfile paths during command parsing so onboarding exits before starting gateway, inference, or sandbox setup side effects. Made-with: Cursor Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
a9ee1bc to
5c99bc1
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/lib/onboard-command.ts (1)
75-79:⚠️ Potential issue | 🟠 MajorReject non-file
--frompaths during parse-time validation.At Line 76, existence-only validation still accepts directories. That breaks the “invalid Dockerfile path fails immediately” guarantee.
Suggested fix
- if (!fs.existsSync(resolvedFromDockerfile)) { + if (!fs.existsSync(resolvedFromDockerfile) || !fs.statSync(resolvedFromDockerfile).isFile()) { error(` --from path not found: ${resolvedFromDockerfile}`); exit(1); }Use this read-only check to confirm current behavior and test coverage:
#!/bin/bash set -euo pipefail echo "Check parse-time --from validation logic:" rg -n --type=ts 'resolvedFromDockerfile|existsSync|statSync|isFile|--from path not found' src/lib/onboard-command.ts echo echo "Check tests for directory-path rejection and fast-fail behavior:" rg -n --type=ts 'path not found|--from|runOnboard|directory|isFile' src/lib/onboard-command.test.ts🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/onboard-command.ts` around lines 75 - 79, The current parse-time validation only checks fs.existsSync(resolvedFromDockerfile) which allows directories; replace the existence-only check with a file check by using fs.statSync(resolvedFromDockerfile).isFile() (or lstatSync) and if it returns false call error(...) and exit(1) to reject non-file --from paths; update any related tests (onboard-command.test.ts) to assert directories are rejected and maintain the same error message/fast-fail behavior used where requestedFromDockerfile, resolvedFromDockerfile, error, and exit are referenced.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/lib/onboard-command.ts`:
- Around line 75-79: The current parse-time validation only checks
fs.existsSync(resolvedFromDockerfile) which allows directories; replace the
existence-only check with a file check by using
fs.statSync(resolvedFromDockerfile).isFile() (or lstatSync) and if it returns
false call error(...) and exit(1) to reject non-file --from paths; update any
related tests (onboard-command.test.ts) to assert directories are rejected and
maintain the same error message/fast-fail behavior used where
requestedFromDockerfile, resolvedFromDockerfile, error, and exit are referenced.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 9f6a9c9e-dbdc-4c42-a060-1052f3619033
📒 Files selected for processing (2)
src/lib/onboard-command.test.tssrc/lib/onboard-command.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/lib/onboard-command.test.ts
jyaunches
left a comment
There was a problem hiding this comment.
LGTM — clean, focused fix. Early validation of --from path prevents side effects. Tests are solid.
## Summary Refreshes the daily docs from NemoClaw commits merged in the past 24 hours and advances the docs metadata from 0.0.29 to 0.0.31, the next version after tag v0.0.30. The updates cover documented behavior gaps found in the merged PRs listed below. ## Related Issue None. ## Changes - `docs/versions1.json` and `docs/project.json`: bump the preferred docs version to `0.0.31` for daily release preparation after latest tag `v0.0.30`. - `docs/reference/commands.md`: document non-interactive Brave Search validation fallback from #2511 / 9bfe30b, missing `--from <Dockerfile>` path validation from #2597 / 7186834, and `logs` reading OpenShell audit events from #2590 / e225dfb. - `docs/inference/use-local-inference.md`: document local inference reachability retry and host-side fallback from #2453 / 9dbe855, plus compatible-endpoint timeout coverage from #2583 / b4ef3db. - `docs/reference/troubleshooting.md`: document source-install shim fallback from #2520 / 01a177c, TLS gateway trust recovery from #1936 / 24725d2, compatible-endpoint timeout coverage from #2583 / b4ef3db, local reachability diagnostics from #2453 / 9dbe855, and host proxy `NO_PROXY` injection from #2662 / b4df07e. ## 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) Additional verification: - `python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix nemoclaw-user --dry-run` passed. - `git diff --check` passed. - Pre-push hooks passed through markdownlint, docs-to-skills, JSON checks, gitleaks, and version sync before `Test (skills YAML)` failed because this fresh worktree lacked `vitest/config`. - `npx prek run --all-files` could not run from the fresh worktree because `npx prek` resolved to a missing `prek@*` package; downloading `@j178/prek` was not approved. - `npm test` could not complete from the fresh worktree because dependencies and compiled `dist/lib/*` artifacts were absent. ## AI Disclosure - [x] AI-assisted — tool: OpenAI Codex --- Signed-off-by: Miyoung Choi <miyoungc@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Version updated to 0.0.31 * Local inference onboarding now includes retry logic for container reachability checks * Web search setup failure handling clarified with fallback guidance * Dockerfile path validation timing documented * Logging behavior clarified for concurrent stream reading * New TLS/certificate troubleshooting section added * Install path and proxy configuration troubleshooting updated <!-- end of auto-generated comment: release notes by coderabbit.ai --> Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
…IA#2597) ## Summary - Validate `nemoclaw onboard --from <Dockerfile>` during command parsing when the path is missing. - Exit before calling the onboarding flow so bad paths do not start preflight, gateway, inference, or sandbox setup side effects. - Add regression coverage that asserts `runOnboard` is not called for a missing `--from` path. ## Test plan - `npm run build:cli` - `npm run typecheck:cli` - `npm test -- src/lib/onboard-command.test.ts` - Manual Brev check: `node ./bin/nemoclaw.js onboard --from /tmp/no-such-dockerfile-2589 --non-interactive --yes-i-accept-third-party-software` exits immediately with `--from path not found:` before `[1/8] Preflight checks` Fixes NVIDIA#2589 Made with [Cursor](https://cursor.com) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved validation for the `--from <Dockerfile>` argument: provided paths are resolved to absolute locations, missing targets produce a clear error message and the command exits with a failure status. * **Tests** * Added tests exercising real, temporary Dockerfile paths and the failure path when a referenced Dockerfile does not exist. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Signed-off-by: Julie Yaunches <jyaunches@nvidia.com> Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
## Summary Refreshes the daily docs from NemoClaw commits merged in the past 24 hours and advances the docs metadata from 0.0.29 to 0.0.31, the next version after tag v0.0.30. The updates cover documented behavior gaps found in the merged PRs listed below. ## Related Issue None. ## Changes - `docs/versions1.json` and `docs/project.json`: bump the preferred docs version to `0.0.31` for daily release preparation after latest tag `v0.0.30`. - `docs/reference/commands.md`: document non-interactive Brave Search validation fallback from NVIDIA#2511 / 9bfe30b, missing `--from <Dockerfile>` path validation from NVIDIA#2597 / 7186834, and `logs` reading OpenShell audit events from NVIDIA#2590 / e225dfb. - `docs/inference/use-local-inference.md`: document local inference reachability retry and host-side fallback from NVIDIA#2453 / 9dbe855, plus compatible-endpoint timeout coverage from NVIDIA#2583 / b4ef3db. - `docs/reference/troubleshooting.md`: document source-install shim fallback from NVIDIA#2520 / 01a177c, TLS gateway trust recovery from NVIDIA#1936 / 24725d2, compatible-endpoint timeout coverage from NVIDIA#2583 / b4ef3db, local reachability diagnostics from NVIDIA#2453 / 9dbe855, and host proxy `NO_PROXY` injection from NVIDIA#2662 / b4df07e. ## 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) Additional verification: - `python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix nemoclaw-user --dry-run` passed. - `git diff --check` passed. - Pre-push hooks passed through markdownlint, docs-to-skills, JSON checks, gitleaks, and version sync before `Test (skills YAML)` failed because this fresh worktree lacked `vitest/config`. - `npx prek run --all-files` could not run from the fresh worktree because `npx prek` resolved to a missing `prek@*` package; downloading `@j178/prek` was not approved. - `npm test` could not complete from the fresh worktree because dependencies and compiled `dist/lib/*` artifacts were absent. ## AI Disclosure - [x] AI-assisted — tool: OpenAI Codex --- Signed-off-by: Miyoung Choi <miyoungc@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Version updated to 0.0.31 * Local inference onboarding now includes retry logic for container reachability checks * Web search setup failure handling clarified with fallback guidance * Dockerfile path validation timing documented * Logging behavior clarified for concurrent stream reading * New TLS/certificate troubleshooting section added * Install path and proxy configuration troubleshooting updated <!-- end of auto-generated comment: release notes by coderabbit.ai --> Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
Summary
nemoclaw onboard --from <Dockerfile>during command parsing when the path is missing.runOnboardis not called for a missing--frompath.Test plan
npm run build:clinpm run typecheck:clinpm test -- src/lib/onboard-command.test.tsnode ./bin/nemoclaw.js onboard --from /tmp/no-such-dockerfile-2589 --non-interactive --yes-i-accept-third-party-softwareexits immediately with--from path not found:before[1/8] Preflight checksFixes #2589
Made with Cursor
Summary by CodeRabbit
Bug Fixes
--from <Dockerfile>argument: provided paths are resolved to absolute locations, missing targets produce a clear error message and the command exits with a failure status.Tests
Signed-off-by: Julie Yaunches jyaunches@nvidia.com