Skip to content

fix(preflight): auto-create swap on low-memory VMs to prevent OOM during sandbox build - #419

Merged
cv merged 13 commits into
NVIDIA:mainfrom
vl43den:fix/swap-preflight
Mar 30, 2026
Merged

fix(preflight): auto-create swap on low-memory VMs to prevent OOM during sandbox build#419
cv merged 13 commits into
NVIDIA:mainfrom
vl43den:fix/swap-preflight

Conversation

@vl43den

@vl43den vl43den commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Description

This PR addresses Out-of-Memory (OOM) crashes encountered during sandbox creation on VMs with 8GB RAM (such as my tested instance on Ubuntu 24.04 droplets).

Previously, the preflight memory check only triggered swap space creation if the total memory was below 6GB. However, the OpenShell sandbox creation process realistically requires more than 8GB total virtual memory (RAM + swap) to handle image compression and buffering without being OOM killed.

This change raises the automatic swap creation threshold from 6000MB to 12000MB. Now, systems with exactly 8GB RAM will correctly trigger the preflight check to naturally provision a 4GB swap space, ensuring the sandbox build survives without returning Exit 137.

Fixes

Production Hardening (Added in latest commits)

  • User Consent Pipeline: Added an interactive [Y/n] confirmation prompt before running any sudo swap commands.
  • Disk Space Checks: Added a free disk space check (~5GB) to prevent disk exhaustion.
  • Swap Verification: Verifies the swap file is actually active in /proc/swaps before short-circuiting.
  • Wider Compatibility: Switched from fallocate to dd for broader filesystem compatibility (e.g., XFS/btrfs).
  • Graceful Cleanup: Added 4GB /swapfile unmount and robust fstab removal to uninstall.sh, along with best-effort cleanup on partial creation failure.

Environment Tested

  • OS: Ubuntu 24.04
  • Host: DigitalOcean Droplet
  • RAM: 8GB (+ 4GB provisioned swap)

Verification Results

  • Pre-fix: nemoclaw onboard consistently failed during "Pushing image" with Command failed (exit 137). free -h showed 0B swap.
  • Post-fix: Preflight correctly identified 7941MB RAM, checked disk storage, auto-provisioned 4GB swap, and the sandbox build completed successfully.

Note: In the latest commits an interactive [Y/n] prompt was added for safety. Verified the interactive prompt and swap allocation flow on a fresh 8GB droplet.

image

After prompting "Y" Swap was checked:

image

Swap Space Usage [check at Step 22/22]:

image

Success step, proceeding to next step:

image

Summary by CodeRabbit

  • New Features

    • Linux onboarding/setup detect low total memory (<12 GB), report RAM/swap/total, and offer to create/enable a 4 GB swap interactively (non-interactive skips); pre-build scripts perform the same check and warn if disk space prevents swap creation.
  • Documentation

    • Added troubleshooting for OOM (exit 137) with manual swap creation steps.
  • Tests

    • Added tests covering memory inspection and swap remediation outcomes.
  • Chores

    • Uninstall now can remove the managed swapfile (gated by state marker and interactive/TTY checks).

@coderabbitai

coderabbitai Bot commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Linux memory inspection and conditional swap remediation: new getMemoryInfo and ensureSwap in preflight, integrated into onboarding and setup to detect low RAM and optionally create/activate a 4 GB /swapfile; uninstall now removes that swapfile; tests and troubleshooting docs updated.

Changes

Cohort / File(s) Summary
Preflight Library
bin/lib/preflight.js
Added getMemoryInfo(opts) to read RAM+swap (Linux/macOS) and ensureSwap(minTotalMB, opts) to check totals and perform Linux-only swap creation/activation (supports dry-run and injected hooks). Exports updated to include both.
Onboarding Flow
bin/lib/onboard.js
Imported getMemoryInfo and ensureSwap; extended preflight() to inspect memory and, on Linux when total < 12000 MB, prompt (interactive) or skip (non-interactive) and call ensureSwap(12000); existing return path preserved.
Setup Script
scripts/setup.sh
Added Linux pre-build memory+swap check using /proc/meminfo; warns on low total, verifies disk free space, and prints manual commands to create a 4 GB /swapfile if needed before sandbox build.
Uninstall Script
uninstall.sh
Added remove_nemoclaw_swap() to conditionally deactivate/remove /swapfile and clean /etc/fstab when a NemoClaw-managed marker exists; gated by interactivity/TTY and invoked during uninstall.
Tests
test/preflight.test.js
Added Vitest suites for getMemoryInfo() parsing/platform handling and ensureSwap() behaviors (threshold pass, dry-run creation, existing-swap suppression, non-Linux skip, missing-memory error).
Documentation
docs/reference/troubleshooting.md
Added “Sandbox creation killed by OOM (exit 137)” section describing low-RAM failure mode, the 4 GB swap remediation, and manual swap creation commands.

Sequence Diagram(s)

sequenceDiagram
  participant User as CLI User
  participant Onboard as onboard.js
  participant Preflight as bin/lib/preflight
  participant OS as OS/Shell
  participant Sandbox as Sandbox Builder

  User->>Onboard: run "nemoclaw onboard"
  Onboard->>Preflight: call getMemoryInfo()
  Preflight->>OS: read /proc/meminfo or run sysctl
  OS-->>Preflight: return memory+swap totals
  Preflight-->>Onboard: return totals
  alt Linux and total < threshold
    Onboard->>User: prompt to create 4 GB swap (interactive)
    User-->>Onboard: consent or decline
    Onboard->>Preflight: call ensureSwap(12000)
    Preflight->>OS: check /swapfile, create/enable swap, update /etc/fstab
    OS-->>Preflight: creation/activation result
    Preflight-->>Onboard: {ok, swapCreated?, reason?}
  else Memory OK or non-Linux
    Onboard-->>Onboard: log "Memory OK" / skip swap
  end
  Onboard->>Sandbox: continue sandbox creation
  Sandbox-->>User: sandbox create result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇
I sniff the RAM and count each byte,
If memory's thin I hop all night,
Four gigabytes to mend the heap,
Sandboxes wake from restful sleep,
Hooray—the builds no longer bite!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% 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 accurately describes the main change: auto-creating swap on low-memory systems to prevent OOM during sandbox build, which is the core objective addressed by all file changes.
Linked Issues check ✅ Passed The PR implements comprehensive swap auto-provisioning [#302] to prevent OOM (exit 137) on low-memory VMs, with memory detection, user prompts, disk-space checks, and ownership tracking for uninstall.
Out of Scope Changes check ✅ Passed All changes are directly scoped to swap/memory provisioning: preflight detection and creation logic, onboard integration with user prompts, documentation updates, setup.sh memory checks, and uninstall cleanup—no unrelated modifications detected.

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

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

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
scripts/setup.sh (1)

176-176: Risk of duplicate /etc/fstab entries on re-runs.

If /swapfile is manually deleted and the script is re-run, the /etc/fstab append will create duplicate entries. Consider checking for existing entry first.

Proposed fix
-    echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
+    grep -q '/swapfile' /etc/fstab || echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/setup.sh` at line 176, Avoid appending a duplicate fstab entry by
checking /etc/fstab for the exact line '/swapfile none swap sw 0 0' before
running the echo/tee append; in the setup.sh code where you currently call "echo
'/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab", add a conditional that
greps /etc/fstab for that exact string and only performs the append when not
found, ensuring idempotent behavior on re-runs.
bin/lib/preflight.js (1)

218-221: Potential duplicate /etc/fstab entry if swapfile was previously removed manually.

Similar to the shell script, if a user manually removes /swapfile but the fstab entry remains from a previous run, this will append a duplicate entry.

Proposed fix
-    runCapture(
-      "echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab",
-      { ignoreError: false }
-    );
+    runCapture(
+      "grep -q '/swapfile' /etc/fstab || echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab",
+      { ignoreError: false }
+    );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/preflight.js` around lines 218 - 221, The current runCapture call
unconditionally appends "/swapfile none swap sw 0 0" to /etc/fstab which can
create duplicate entries; update the runCapture invocation that contains the
command string "echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab" to
first check /etc/fstab for the exact line and only append if missing (for
example using a grep check or similar conditional) so the line is not added
twice if it already exists; keep the change local to the runCapture call in
preflight.js.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@bin/lib/onboard.js`:
- Around line 333-340: The current log treats `{ ok: true, swapCreated: false }`
as "Memory OK" even when memory is low; update the conditional handling around
swapResult and mem in the onboard.js branch that prints `Memory OK:
${mem.totalRamMB} MB RAM + ${mem.totalSwapMB} MB swap` so it distinguishes a
pre-existing swap from a successful creation and reports accurate status: if
swapResult.swapCreated is false and total RAM+swap is still below the threshold
(e.g., 12000 MB) log a warning that swap already existed but memory is still low
(include mem.totalRamMB and mem.totalSwapMB and swapResult.reason/state),
otherwise keep the positive message when totals are sufficient; adjust messages
around ensureSwap/swapResult to reflect swap pre-existence vs newly created
swap.

In `@scripts/setup.sh`:
- Line 166: The MIN_TOTAL_MB constant in setup.sh is set to 6144 which conflicts
with the 12000 MB requirement enforced elsewhere (ensureSwap and preflight
defaults); update MIN_TOTAL_MB to 12000 so the shell setup check aligns with
bin/lib/onboard.js's ensureSwap(12000) and bin/lib/preflight.js defaults,
ensuring the VM memory/swap preflight threshold is consistent across scripts.

---

Nitpick comments:
In `@bin/lib/preflight.js`:
- Around line 218-221: The current runCapture call unconditionally appends
"/swapfile none swap sw 0 0" to /etc/fstab which can create duplicate entries;
update the runCapture invocation that contains the command string "echo
'/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab" to first check /etc/fstab
for the exact line and only append if missing (for example using a grep check or
similar conditional) so the line is not added twice if it already exists; keep
the change local to the runCapture call in preflight.js.

In `@scripts/setup.sh`:
- Line 176: Avoid appending a duplicate fstab entry by checking /etc/fstab for
the exact line '/swapfile none swap sw 0 0' before running the echo/tee append;
in the setup.sh code where you currently call "echo '/swapfile none swap sw 0 0'
| sudo tee -a /etc/fstab", add a conditional that greps /etc/fstab for that
exact string and only performs the append when not found, ensuring idempotent
behavior on re-runs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0ddd2bc0-4f6c-4a6f-b97a-5585af63ea2c

📥 Commits

Reviewing files that changed from the base of the PR and between 20a63d0 and 6abf734.

📒 Files selected for processing (5)
  • bin/lib/onboard.js
  • bin/lib/preflight.js
  • docs/reference/troubleshooting.md
  • scripts/setup.sh
  • test/preflight.test.js

Comment thread bin/lib/onboard.js Outdated
Comment thread scripts/setup.sh Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
bin/lib/preflight.js (1)

228-245: Consider cleanup on partial failure.

If swap creation fails partway (e.g., dd succeeds but mkswap fails), a 4 GB /swapfile remains on disk without being formatted as swap. The helpful error message guides manual recovery, but the orphaned file could be confusing.

🧹 Optional: Clean up on failure
   // Create 4 GB swap file
   try {
     runCapture("sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 status=none", { ignoreError: false });
     runCapture("sudo chmod 600 /swapfile", { ignoreError: false });
     runCapture("sudo mkswap /swapfile", { ignoreError: false });
     runCapture("sudo swapon /swapfile", { ignoreError: false });
     runCapture(
       "grep -q '/swapfile' /etc/fstab || echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab",
       { ignoreError: false }
     );
     return { ok: true, totalMB: mem.totalMB + 4096, swapCreated: true };
   } catch (err) {
+    // Attempt cleanup of partial state
+    try {
+      runCapture("sudo swapoff /swapfile 2>/dev/null || true", { ignoreError: true });
+      runCapture("sudo rm -f /swapfile", { ignoreError: true });
+    } catch {
+      // Best effort cleanup
+    }
     return {
       ok: false,
       reason: `swap creation failed: ${err.message}. Create swap manually:\n` +
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/preflight.js` around lines 228 - 245, The try/catch that creates swap
via runCapture may leave a partial /swapfile if a later step fails; modify the
catch in the swap-creation block to attempt cleanup before returning: call
runCapture to sudo swapoff /swapfile (ignore failures), remove any /swapfile
entry from /etc/fstab (e.g. via sudo sed -i to delete lines containing
'/swapfile', ignore failures), and remove the file with sudo rm -f /swapfile
(ignore failures), then return the existing error response; reference the swap
creation sequence using runCapture and the catch block surrounding
runCapture("sudo dd ..."), runCapture("sudo mkswap /swapfile", ...) etc., to
implement the cleanup steps.
uninstall.sh (1)

409-411: Sed pattern may miss fstab entries with variant whitespace.

The pattern /swapfile none swap sw 0 0 requires exact spacing. If /etc/fstab was manually edited or if future code changes the format (e.g., tabs instead of spaces), this cleanup would silently leave the entry behind.

Consider a more permissive pattern:

🔧 Proposed fix for more robust fstab cleanup
   if grep -q '/swapfile' /etc/fstab 2>/dev/null; then
-    sudo sed -i '\|/swapfile none swap sw 0 0|d' /etc/fstab
+    sudo sed -i '\|^/swapfile[[:space:]]|d' /etc/fstab
     info "Removed /swapfile entry from /etc/fstab"
   fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uninstall.sh` around lines 409 - 411, The sed removal currently uses an exact
string match ('/swapfile none swap sw 0 0') which will miss lines with tabs or
extra/missing spaces; update the sed invocation that targets /etc/fstab (the
current sed -i '\|/swapfile none swap sw 0 0|d' call referencing '/swapfile') to
use a whitespace-tolerant regex (e.g., match '/swapfile' followed later by
'swap' and/or allow '\s\+' between fields) or match any line starting with
'/swapfile' containing 'swap' so entries with tabs/variant spacing are removed
reliably, and keep the info "Removed /swapfile entry from /etc/fstab" message
intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@bin/lib/preflight.js`:
- Around line 228-245: The try/catch that creates swap via runCapture may leave
a partial /swapfile if a later step fails; modify the catch in the swap-creation
block to attempt cleanup before returning: call runCapture to sudo swapoff
/swapfile (ignore failures), remove any /swapfile entry from /etc/fstab (e.g.
via sudo sed -i to delete lines containing '/swapfile', ignore failures), and
remove the file with sudo rm -f /swapfile (ignore failures), then return the
existing error response; reference the swap creation sequence using runCapture
and the catch block surrounding runCapture("sudo dd ..."), runCapture("sudo
mkswap /swapfile", ...) etc., to implement the cleanup steps.

In `@uninstall.sh`:
- Around line 409-411: The sed removal currently uses an exact string match
('/swapfile none swap sw 0 0') which will miss lines with tabs or extra/missing
spaces; update the sed invocation that targets /etc/fstab (the current sed -i
'\|/swapfile none swap sw 0 0|d' call referencing '/swapfile') to use a
whitespace-tolerant regex (e.g., match '/swapfile' followed later by 'swap'
and/or allow '\s\+' between fields) or match any line starting with '/swapfile'
containing 'swap' so entries with tabs/variant spacing are removed reliably, and
keep the info "Removed /swapfile entry from /etc/fstab" message intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b4398e22-34c5-44d5-82cf-b9e9db825de3

📥 Commits

Reviewing files that changed from the base of the PR and between 3a30851 and 9a07903.

📒 Files selected for processing (5)
  • bin/lib/onboard.js
  • bin/lib/preflight.js
  • docs/reference/troubleshooting.md
  • scripts/setup.sh
  • uninstall.sh
✅ Files skipped from review due to trivial changes (1)
  • docs/reference/troubleshooting.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • bin/lib/onboard.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
bin/lib/preflight.js (2)

239-247: Remove redundant dryRun check in cleanup block.

The if (!o.dryRun) check on line 241 is unreachable dead code. This catch block can only be reached when dryRun is false, since line 223 returns early when dryRun is true.

♻️ Proposed simplification
   } catch (err) {
     // Attempt cleanup of partial state
     try {
-      if (!o.dryRun) {
-        runCapture("sudo swapoff /swapfile 2>/dev/null || true", { ignoreError: true });
-        runCapture("sudo rm -f /swapfile", { ignoreError: true });
-      }
+      runCapture("sudo swapoff /swapfile 2>/dev/null || true", { ignoreError: true });
+      runCapture("sudo rm -f /swapfile", { ignoreError: true });
     } catch {
       // Best effort cleanup
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/preflight.js` around lines 239 - 247, The cleanup try/catch contains
an unnecessary conditional around o.dryRun because the function returns earlier
when o.dryRun is true; remove the redundant "if (!o.dryRun)" guard and have the
try block directly call runCapture("sudo swapoff /swapfile 2>/dev/null || true",
{ ignoreError: true }) and runCapture("sudo rm -f /swapfile", { ignoreError:
true }) so the cleanup is attempted unconditionally in that catch path (keep the
surrounding try/catch and the ignoreError options intact); refer to the
runCapture calls and the o.dryRun variable to locate and update the code.

182-205: Consider handling inactive swapfile edge case.

The check at line 185 verifies /swapfile exists but doesn't confirm it's actually activated as swap. If someone previously created the file but never ran swapon, or if it was disabled, the system could still be low on virtual memory.

This is a minor edge case, and the current behavior (not recreating an existing file) is reasonable to avoid data loss. You could optionally verify activation via /proc/swaps:

♻️ Optional enhancement to verify swap is active
   // Check if swap file already exists
   if (!o.dryRun) {
     try {
       fs.accessSync("/swapfile");
+      // Optionally verify it's actually in use
+      const swaps = fs.readFileSync("/proc/swaps", "utf-8");
+      if (!swaps.includes("/swapfile")) {
+        // File exists but isn't active — attempt to activate it
+        runCapture("sudo swapon /swapfile", { ignoreError: true });
+      }
       return {
         ok: true,
         totalMB: mem.totalMB,
         swapCreated: false,
         reason: "/swapfile already exists",
       };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/preflight.js` around lines 182 - 205, The current early-return when
fs.accessSync("/swapfile") succeeds does not verify the file is actually active
as swap; after detecting the file exists (fs.accessSync) (and in dry-run using
o.swapfileExists), read /proc/swaps and check for an entry matching "/swapfile"
and only return the "already exists" result if that entry is present (i.e., swap
is active); if the file exists but is not listed in /proc/swaps, fall through so
the code will enable/create the swap (and in dry-run allow simulating this via a
new o.swapfileActive flag), preserving the existing returned shape (ok, totalMB,
swapCreated, reason) when appropriate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@bin/lib/preflight.js`:
- Around line 239-247: The cleanup try/catch contains an unnecessary conditional
around o.dryRun because the function returns earlier when o.dryRun is true;
remove the redundant "if (!o.dryRun)" guard and have the try block directly call
runCapture("sudo swapoff /swapfile 2>/dev/null || true", { ignoreError: true })
and runCapture("sudo rm -f /swapfile", { ignoreError: true }) so the cleanup is
attempted unconditionally in that catch path (keep the surrounding try/catch and
the ignoreError options intact); refer to the runCapture calls and the o.dryRun
variable to locate and update the code.
- Around line 182-205: The current early-return when fs.accessSync("/swapfile")
succeeds does not verify the file is actually active as swap; after detecting
the file exists (fs.accessSync) (and in dry-run using o.swapfileExists), read
/proc/swaps and check for an entry matching "/swapfile" and only return the
"already exists" result if that entry is present (i.e., swap is active); if the
file exists but is not listed in /proc/swaps, fall through so the code will
enable/create the swap (and in dry-run allow simulating this via a new
o.swapfileActive flag), preserving the existing returned shape (ok, totalMB,
swapCreated, reason) when appropriate.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6e4b3a53-b82e-4b2f-97a1-a2633abf691f

📥 Commits

Reviewing files that changed from the base of the PR and between 9a07903 and 06233c7.

📒 Files selected for processing (2)
  • bin/lib/preflight.js
  • uninstall.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • uninstall.sh

@vl43den
vl43den force-pushed the fix/swap-preflight branch from 06233c7 to f4a6a07 Compare March 19, 2026 21:30
@psorensen-nvidia psorensen-nvidia added bug platform: ubuntu Affects Ubuntu Linux environments labels Mar 19, 2026
@kjw3

kjw3 commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Thanks for working on a real issue here. The low-memory OOM problem is valid, and the 12 GB total-memory check is directionally reasonable, but I’m not comfortable merging this as written.

The main problem is that the PR expands the fix into automatic host swap lifecycle management in ways that are too risky for product behavior.

  • In bin/lib/onboard.js, non-interactive onboard will still try to create swap with sudo because the flow defaults to proceeding when there is no prompt. An unattended onboard should not silently mutate host swap state.
  • In scripts/setup.sh, the legacy setup path now creates /swapfile automatically with sudo and no explicit user consent. That is too broad for a setup script.
  • In uninstall.sh, the cleanup logic treats any 4 GB /swapfile as NemoClaw-managed. That provenance check is too weak and could remove a pre-existing host swapfile that NemoClaw did not create.

I’d be happy to re-review if you narrow this so the OOM mitigation is preserved without silent host-state mutation. Concretely, the next revision should:

  • require explicit user consent for swap creation in interactive flows
  • avoid auto-creating swap in non-interactive/setup flows
  • only remove swap on uninstall when NemoClaw can prove it created and owns that swapfile

The underlying issue is worth fixing. This just needs a tighter product boundary around host mutation before it can merge.

@vl43den

vl43den commented Mar 24, 2026

Copy link
Copy Markdown
Contributor Author

Thank you very much for the review! In order to ensure a more robust solution I have:

  1. changed the consent to be explicitly required [Y/n] to [y/N] and enforce .startsWith("y")
  2. disabled silent execution by changing onboard.js to default to false and replaced sudo dd with a warning message containing the required command for the user to execute.
  3. implemented proof of ownership by using a strict file-marker pattern ~/.nemoclaw/managed_swap so uninstall.sh will only touch /swapfile if NemoClaw can definitively prove it was the original author
  4. fixed my implementation after running the uninstaller and noticing an ordering bug: during testing:"remove_nemoclaw_state" was wiping "~/.nemoclaw" slightly before "remove_nemoclaw_swap" could run. I swapped the execution order in "uninstall.sh" so the marker file can be successfully read and validated before the state directory is destroyed.

I documented the main anchors of the process by spinning up another droplet and installing the adjusted version, I'm eager to help tighten this more with your help, if needed, so this can reach production grade:

Changed prompt requiring y:
image

Swap space being allocated after prompting y:
image
image

Situation after ending deployment:

image

Uninstalling deployment with bash uninstall.sh:

image image

Testing behavior with a manually created marker:

image

@prekshivyas prekshivyas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kjw3's. three concerns from the previous review look addressed:

  1. Interactive consent now defaults to [y/N] with explicit startsWith("y") — non-interactive mode skips swap creation entirely.
  2. scripts/setup.sh only warns, never auto-creates swap. Correct.
  3. Uninstall checks ~/.nemoclaw/managed_swap marker before touching /swapfile.

Needs a rebase — docs/reference/troubleshooting.md conflicts with #911 (merged last week, added reconnect-after-reboot section under Runtime).

One minor nit: bin/lib/preflight.js ~L230 loads require("path") and require("os") inside ensureSwap() — move them to the top of the file with the other requires.
@vl43den

vl43den and others added 9 commits March 26, 2026 18:59
… build

On DigitalOcean Ubuntu 24.04 droplets (and similar VMs) with 8 GB RAM
and no swap, the sandbox image push during onboarding gets OOM-killed
(exit 137).

Changes:
- Add getMemoryInfo() and ensureSwap() to bin/lib/preflight.js
- Integrate memory/swap check into onboard preflight step (onboard.js)
- Add equivalent swap check to scripts/setup.sh
- Add unit tests for getMemoryInfo and ensureSwap
- Document OOM troubleshooting in docs/reference/troubleshooting.md

The preflight now detects low memory (<6 GB RAM+swap) and auto-creates
a 4 GB swap file via sudo. If swap creation fails, it warns the user
with manual steps instead of hard-failing.
prevent misleading "Memory OK" logs when RAM is low but an existing swapfile is safely providing coverage

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
align the MIN_TOTAL_MB constant with the 12000MB threshold enforced in the JS preflight checks

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@vl43den
vl43den force-pushed the fix/swap-preflight branch from a75107c to df9f073 Compare March 26, 2026 18:33
@vl43den

vl43den commented Mar 26, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Mar 26, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
uninstall.sh (1)

494-526: Well-structured ownership verification before swap cleanup.

The function correctly implements the ownership proof pattern requested in PR feedback:

  1. Verifies /swapfile exists before attempting cleanup
  2. Validates the marker file at $NEMOCLAW_STATE_DIR/managed_swap exists and contains /swapfile
  3. Skips cleanup in non-interactive mode (consistent with remove_file_with_optional_sudo)
  4. Uses || true after swapoff for graceful handling if already deactivated

The sed pattern \|^/swapfile[[:space:]]|d correctly matches the fstab entry format /swapfile none swap sw 0 0 written by preflight.js.

One minor robustness consideration: after sudo rm -f /swapfile on line 519, there's no verification the removal succeeded. If rm fails (e.g., immutable attribute set), the function reports success but the file remains.

Optional: Add verification after removal
   sudo swapoff /swapfile 2>/dev/null || true
-  sudo rm -f /swapfile
+  if ! sudo rm -f /swapfile; then
+    warn "Failed to remove /swapfile"
+    return 1
+  fi
   # Clean fstab entry
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uninstall.sh` around lines 494 - 526, The remove_nemoclaw_swap function
currently deletes /swapfile with sudo rm -f but doesn't verify the removal; add
a post-removal check immediately after the sudo rm -f in remove_nemoclaw_swap to
test whether /swapfile still exists (e.g., [ -f /swapfile ]), and if it does,
log an error or warn via warn/processLogger and return a non-zero status (or set
a failure flag) so the caller knows cleanup failed; if the file is gone,
continue to clean fstab and report success as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/preflight.test.js`:
- Around line 207-214: The test currently relies on memoryInfo: null which
causes ensureSwap to call getMemoryInfo and makes the test
environment-dependent; instead, mock or stub getMemoryInfo to deterministically
simulate "unavailable" memory info and then call ensureSwap with memoryInfo
explicitly set to null (or left undefined) to force the error branch.
Specifically, in test/preflight.test.js replace the current case with a stub of
the getMemoryInfo function (e.g., using sinon.stub or your test framework's
mocking) so getMemoryInfo returns null or throws, call ensureSwap(...) (the
symbol ensureSwap) with platform "linux" and memoryInfo null, assert result.ok
is false and reason matches /could not read memory info/, and finally restore
the stubbed getMemoryInfo to avoid affecting other tests.

---

Nitpick comments:
In `@uninstall.sh`:
- Around line 494-526: The remove_nemoclaw_swap function currently deletes
/swapfile with sudo rm -f but doesn't verify the removal; add a post-removal
check immediately after the sudo rm -f in remove_nemoclaw_swap to test whether
/swapfile still exists (e.g., [ -f /swapfile ]), and if it does, log an error or
warn via warn/processLogger and return a non-zero status (or set a failure flag)
so the caller knows cleanup failed; if the file is gone, continue to clean fstab
and report success as before.
🪄 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: Pro

Run ID: afe3dfaf-ef85-4a89-a392-46585b36662a

📥 Commits

Reviewing files that changed from the base of the PR and between 9a07903 and df9f073.

📒 Files selected for processing (6)
  • bin/lib/onboard.js
  • bin/lib/preflight.js
  • docs/reference/troubleshooting.md
  • scripts/setup.sh
  • test/preflight.test.js
  • uninstall.sh
✅ Files skipped from review due to trivial changes (1)
  • docs/reference/troubleshooting.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • bin/lib/onboard.js
  • bin/lib/preflight.js

Comment thread test/preflight.test.js
@vl43den
vl43den force-pushed the fix/swap-preflight branch from b880a0f to 1cf4142 Compare March 26, 2026 18:46
@vl43den

vl43den commented Mar 26, 2026

Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Mar 26, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
test/preflight.test.js (1)

207-221: ⚠️ Potential issue | 🟠 Major

Make the unavailable-memory test deterministic (current stub likely doesn’t affect ensureSwap).

At Line 210, mutating preflight.getMemoryInfo may not intercept the lexical getMemoryInfo(...) call inside ensureSwap, so this can still depend on host /proc/meminfo and become flaky.

Proposed deterministic fix
+import { assert, describe, expect, it, vi } from "vitest";
...
 it("returns error when memory info is unavailable", () => {
-  const preflight = require("../bin/lib/preflight");
-  const originalGetMemoryInfo = preflight.getMemoryInfo;
-  preflight.getMemoryInfo = () => null;
+  const fs = require("node:fs");
+  const readSpy = vi.spyOn(fs, "readFileSync").mockImplementation((path, ...args) => {
+    if (path === "/proc/meminfo") {
+      throw new Error("EACCES");
+    }
+    return "";
+  });

   try {
-    const result = preflight.ensureSwap(6144, {
+    const result = ensureSwap(6144, {
       platform: "linux",
-      memoryInfo: null,
     });
     assert.equal(result.ok, false);
     assert.match(result.reason, /could not read memory info/);
   } finally {
-    preflight.getMemoryInfo = originalGetMemoryInfo;
+    readSpy.mockRestore();
   }
 });
#!/bin/bash
# Verify whether ensureSwap calls lexical getMemoryInfo (not exported property).
rg -n -C3 'function ensureSwap|const mem = o\.memoryInfo \|\| getMemoryInfo\(' bin/lib/preflight.js

Expected result: ensureSwap contains getMemoryInfo({ platform }) directly, confirming export-object reassignment in the test is not a reliable hook point.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/preflight.test.js` around lines 207 - 221, The test mutates
preflight.getMemoryInfo but ensureSwap calls the lexical getMemoryInfo directly,
so the stub doesn't take effect and the test is flaky; fix by loading the module
with a test-time stub for the internal getMemoryInfo used by ensureSwap (e.g.,
use proxyquire/rewire to require the module while replacing the internal
getMemoryInfo to return null) so ensureSwap sees the deterministic null result;
target the ensureSwap function and the module's internal getMemoryInfo when
replacing the implementation rather than assigning preflight.getMemoryInfo after
require.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@test/preflight.test.js`:
- Around line 207-221: The test mutates preflight.getMemoryInfo but ensureSwap
calls the lexical getMemoryInfo directly, so the stub doesn't take effect and
the test is flaky; fix by loading the module with a test-time stub for the
internal getMemoryInfo used by ensureSwap (e.g., use proxyquire/rewire to
require the module while replacing the internal getMemoryInfo to return null) so
ensureSwap sees the deterministic null result; target the ensureSwap function
and the module's internal getMemoryInfo when replacing the implementation rather
than assigning preflight.getMemoryInfo after require.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 46000274-8fbb-4cdd-aab6-b70e1dccf6bc

📥 Commits

Reviewing files that changed from the base of the PR and between df9f073 and 1cf4142.

📒 Files selected for processing (2)
  • test/preflight.test.js
  • uninstall.sh

@vl43den

vl43den commented Mar 26, 2026

Copy link
Copy Markdown
Contributor Author

Thank you so much for the review @prekshivyas, I've adressed all the points so far:

  1. Rebased onto the latest main and resolved the troubleshooting.md conflict.
  2. Moved the inline require statements to the top-level in preflight.js
  3. Resolved Flaky Test by refactoring ensureSwap() to support a dependency injection point (getMemoryInfoImpl). This fixes the issue where the local call was bypassing the test stub, making the unit test 100% deterministic without needing external mocking libraries.
  4. Hardened Swap Logic: The check now explicitly handles "orphaned" swap files. If /swapfile exists but isn't active (e.g., after a reboot), it will now attempt to reactivate it (swapon) instead of potentially overwriting it with dd.
  5. Marker-file Cleanup: Confirmed that uninstall.sh uses the ~/.nemoclaw/managed_swap marker to ensure only NemoClaw-managed swap is removed.

Let me know if we need to rework something or lend anything a finishing touch!

mafueee pushed a commit to mafueee/NemoClaw that referenced this pull request Mar 28, 2026
@prekshivyas prekshivyas assigned prekshivyas and unassigned kjw3 Mar 30, 2026
@prekshivyas

prekshivyas commented Mar 30, 2026

Copy link
Copy Markdown
Collaborator

@vl43den fya

The CI failure (lint + test-unit) is a single flaky test at test/preflight.test.js:183:

ensureSwap > reports swap would be created in dry-run mode when below threshold
AssertionError: expected false to equal true

Root cause: The test doesn't pass swapfileExists: false, so ensureSwap picks up the live fs.existsSync("/swapfile") default. On CI runners where /swapfile exists, the dry-run path short-circuits to { swapCreated: false } instead of exercising the creation path.

Fix — add swapfileExists: false to the test options (line 180):

   it("reports swap would be created in dry-run mode when below threshold", () => {
     const result = ensureSwap(6144, {
       platform: "linux",
       memoryInfo: { totalRamMB: 4000, totalSwapMB: 0, totalMB: 4000 },
       dryRun: true,
+      swapfileExists: false,
     });

This makes the test deterministic regardless of CI host state — same pattern used by the "skips swap creation when /swapfile already exists" test on line 191.

ensures test is deterministic regardless of CI host state after proposed fix from review
@vl43den

vl43den commented Mar 30, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the quick heads up/root cause analysis @prekshivyas !

@vl43den
vl43den requested a review from prekshivyas March 30, 2026 19:35
@cv
cv merged commit f974a94 into NVIDIA:main Mar 30, 2026
1 check passed
quanticsoul4772 pushed a commit to quanticsoul4772/NemoClaw that referenced this pull request Mar 30, 2026
…ing sandbox build (NVIDIA#419)

* fix: auto-create swap on low-memory VMs to prevent OOM during sandbox build

On DigitalOcean Ubuntu 24.04 droplets (and similar VMs) with 8 GB RAM
and no swap, the sandbox image push during onboarding gets OOM-killed
(exit 137).

Changes:
- Add getMemoryInfo() and ensureSwap() to bin/lib/preflight.js
- Integrate memory/swap check into onboard preflight step (onboard.js)
- Add equivalent swap check to scripts/setup.sh
- Add unit tests for getMemoryInfo and ensureSwap
- Document OOM troubleshooting in docs/reference/troubleshooting.md

The preflight now detects low memory (<6 GB RAM+swap) and auto-creates
a 4 GB swap file via sudo. If swap creation fails, it warns the user
with manual steps instead of hard-failing.

* fix: increase memory threshold for swap creation to 12000MB

* Update bin/lib/onboard.js

prevent misleading "Memory OK" logs when RAM is low but an existing swapfile is safely providing coverage

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update scripts/setup.sh

align the MIN_TOTAL_MB constant with the 12000MB threshold enforced in the JS preflight checks

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: harden swap creation with size checks, interactive prompt, dd, and proper uninstaller cleanup

* fix: address CodeRabbit feedback for swap cleanup and inactive checks

* fix(preflight): address swap management feedback

* fix(preflight): fix swap cleanup ordering and clean up comments

* fix(preflight): move require('path') and require('os') to top-level imports

* fix: address CodeRabbit feedback on preflight tests and uninstaller verification

* fix(preflight): harden swap check to handle reactivation of orphaned swap files

* fix: add swapfileExists false to the test options

ensures test is deterministic regardless of CI host state after proposed fix from review

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
laitingsheng pushed a commit that referenced this pull request Apr 2, 2026
…ing sandbox build (#419)

* fix: auto-create swap on low-memory VMs to prevent OOM during sandbox build

On DigitalOcean Ubuntu 24.04 droplets (and similar VMs) with 8 GB RAM
and no swap, the sandbox image push during onboarding gets OOM-killed
(exit 137).

Changes:
- Add getMemoryInfo() and ensureSwap() to bin/lib/preflight.js
- Integrate memory/swap check into onboard preflight step (onboard.js)
- Add equivalent swap check to scripts/setup.sh
- Add unit tests for getMemoryInfo and ensureSwap
- Document OOM troubleshooting in docs/reference/troubleshooting.md

The preflight now detects low memory (<6 GB RAM+swap) and auto-creates
a 4 GB swap file via sudo. If swap creation fails, it warns the user
with manual steps instead of hard-failing.

* fix: increase memory threshold for swap creation to 12000MB

* Update bin/lib/onboard.js

prevent misleading "Memory OK" logs when RAM is low but an existing swapfile is safely providing coverage

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update scripts/setup.sh

align the MIN_TOTAL_MB constant with the 12000MB threshold enforced in the JS preflight checks

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: harden swap creation with size checks, interactive prompt, dd, and proper uninstaller cleanup

* fix: address CodeRabbit feedback for swap cleanup and inactive checks

* fix(preflight): address swap management feedback

* fix(preflight): fix swap cleanup ordering and clean up comments

* fix(preflight): move require('path') and require('os') to top-level imports

* fix: address CodeRabbit feedback on preflight tests and uninstaller verification

* fix(preflight): harden swap check to handle reactivation of orphaned swap files

* fix: add swapfileExists false to the test options

ensures test is deterministic regardless of CI host state after proposed fix from review

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
lakamsani pushed a commit to lakamsani/NemoClaw that referenced this pull request Apr 4, 2026
…ing sandbox build (NVIDIA#419)

* fix: auto-create swap on low-memory VMs to prevent OOM during sandbox build

On DigitalOcean Ubuntu 24.04 droplets (and similar VMs) with 8 GB RAM
and no swap, the sandbox image push during onboarding gets OOM-killed
(exit 137).

Changes:
- Add getMemoryInfo() and ensureSwap() to bin/lib/preflight.js
- Integrate memory/swap check into onboard preflight step (onboard.js)
- Add equivalent swap check to scripts/setup.sh
- Add unit tests for getMemoryInfo and ensureSwap
- Document OOM troubleshooting in docs/reference/troubleshooting.md

The preflight now detects low memory (<6 GB RAM+swap) and auto-creates
a 4 GB swap file via sudo. If swap creation fails, it warns the user
with manual steps instead of hard-failing.

* fix: increase memory threshold for swap creation to 12000MB

* Update bin/lib/onboard.js

prevent misleading "Memory OK" logs when RAM is low but an existing swapfile is safely providing coverage

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update scripts/setup.sh

align the MIN_TOTAL_MB constant with the 12000MB threshold enforced in the JS preflight checks

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: harden swap creation with size checks, interactive prompt, dd, and proper uninstaller cleanup

* fix: address CodeRabbit feedback for swap cleanup and inactive checks

* fix(preflight): address swap management feedback

* fix(preflight): fix swap cleanup ordering and clean up comments

* fix(preflight): move require('path') and require('os') to top-level imports

* fix: address CodeRabbit feedback on preflight tests and uninstaller verification

* fix(preflight): harden swap check to handle reactivation of orphaned swap files

* fix: add swapfileExists false to the test options

ensures test is deterministic regardless of CI host state after proposed fix from review

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
gemini2026 pushed a commit to gemini2026/NemoClaw that referenced this pull request Apr 14, 2026
…ing sandbox build (NVIDIA#419)

* fix: auto-create swap on low-memory VMs to prevent OOM during sandbox build

On DigitalOcean Ubuntu 24.04 droplets (and similar VMs) with 8 GB RAM
and no swap, the sandbox image push during onboarding gets OOM-killed
(exit 137).

Changes:
- Add getMemoryInfo() and ensureSwap() to bin/lib/preflight.js
- Integrate memory/swap check into onboard preflight step (onboard.js)
- Add equivalent swap check to scripts/setup.sh
- Add unit tests for getMemoryInfo and ensureSwap
- Document OOM troubleshooting in docs/reference/troubleshooting.md

The preflight now detects low memory (<6 GB RAM+swap) and auto-creates
a 4 GB swap file via sudo. If swap creation fails, it warns the user
with manual steps instead of hard-failing.

* fix: increase memory threshold for swap creation to 12000MB

* Update bin/lib/onboard.js

prevent misleading "Memory OK" logs when RAM is low but an existing swapfile is safely providing coverage

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update scripts/setup.sh

align the MIN_TOTAL_MB constant with the 12000MB threshold enforced in the JS preflight checks

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: harden swap creation with size checks, interactive prompt, dd, and proper uninstaller cleanup

* fix: address CodeRabbit feedback for swap cleanup and inactive checks

* fix(preflight): address swap management feedback

* fix(preflight): fix swap cleanup ordering and clean up comments

* fix(preflight): move require('path') and require('os') to top-level imports

* fix: address CodeRabbit feedback on preflight tests and uninstaller verification

* fix(preflight): harden swap check to handle reactivation of orphaned swap files

* fix: add swapfileExists false to the test options

ensures test is deterministic regardless of CI host state after proposed fix from review

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
@wscurran wscurran added area: install Install, setup, prerequisites, or uninstall flow area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: packaging Packages, images, registries, installers, or distribution bug-fix PR fixes a bug or regression platform: container Affects Docker, containerd, Podman, or images and removed area: packaging Packages, images, registries, installers, or distribution priority: medium labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: install Install, setup, prerequisites, or uninstall flow area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow bug-fix PR fixes a bug or regression platform: container Affects Docker, containerd, Podman, or images platform: ubuntu Affects Ubuntu Linux environments

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Killed openshell sandbox create

6 participants