Skip to content

fix(maintenance): skip non-Ready sandboxes in pre-upgrade backup loop - #4256

Merged
ericksoa merged 3 commits into
mainfrom
fix-4233-backup-skip-non-ready
May 27, 2026
Merged

fix(maintenance): skip non-Ready sandboxes in pre-upgrade backup loop#4256
ericksoa merged 3 commits into
mainfrom
fix-4233-backup-skip-non-ready

Conversation

@laitingsheng

@laitingsheng laitingsheng commented May 26, 2026

Copy link
Copy Markdown
Contributor

Summary

nemoclaw backup-all (run by the installer at phase [2/3]) attempted to back up every registered sandbox regardless of state. parseLiveSandboxNames returned every row of openshell sandbox list — including rows with PHASE=Error for stopped containers — so the if (!liveNames.has(sb.name)) skip in src/lib/actions/maintenance.ts:71 never fired for stopped sandboxes. The backup then failed, the installer aborted, and the upgrade was blocked for anyone with a stopped sandbox. nemoclaw upgrade-sandboxes had the same bug: running=true for an Error-phase sandbox, so a stopped sandbox was offered for in-place rebuild instead of being classified as stopped.

Related Issue

Fixes #4233

Changes

  • src/lib/runtime-recovery.ts — new parseReadySandboxNames(listOutput) that mirrors parseLiveSandboxNames but only includes rows whose last whitespace-delimited column equals Ready. Both parsers now share an isNonSandboxRow helper that compares the first column to the literal string "NAME" and the full line to the exact No sandboxes found notice, so sandboxes with names like name-prod or no-sandboxes are no longer dropped by the old /^(NAME|No sandboxes found\.?$)/i regex.
  • src/lib/actions/maintenance.tsbackupAll switches to parseReadySandboxNames, so stopped or errored sandboxes hit the Skipping '<name>' (not running) branch and increment the skipped counter instead of attempting an impossible backup.
  • src/lib/actions/upgrade-sandboxes.ts — same Ready-only swap so classifyUpgradeableSandboxes records running=false for non-Ready sandboxes and splitRebuildableSandboxes routes them through the stopped path.
  • src/lib/runtime-recovery.test.ts — adds a parseReadySandboxNames suite (Ready-only filter against a mixed Ready / Provisioning / Error list, the stopped-container Error row directly, No sandboxes found. / Error: … / protobuf-mismatch lines, and the empty-input fallback) plus a regression case for parseLiveSandboxNames covering name-prod and no-sandboxes names that the old regex skipped.
  • src/lib/actions/gateway-drift-preflight.test.ts — new backup-all skips sandboxes that are not in Ready phase case that drives backupAll end-to-end with a mixed registry and mixed sandbox list output, asserting that backupSandboxState is called for the Ready sandbox only and the skip log fires for the Error-phase sandbox.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • 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
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes
  • make docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Tinson Lai tinsonl@nvidia.com

Summary by CodeRabbit

  • Improvements

    • Backup and upgrade routines now base sandbox selection on Ready-state detection, changing which sandboxes are considered eligible for backup and upgrade operations.
  • Tests

    • Added tests validating Ready-state identification, excluding Error-state sandboxes, and handling edge cases like empty or malformed list output.

Review Change Stack

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@coderabbitai

coderabbitai Bot commented May 26, 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: fd12beac-90cc-45df-86c4-dbd7de799ac0

📥 Commits

Reviewing files that changed from the base of the PR and between d9ef8de and 2641246.

📒 Files selected for processing (4)
  • src/lib/actions/gateway-drift-preflight.test.ts
  • src/lib/actions/upgrade-sandboxes.ts
  • src/lib/runtime-recovery.test.ts
  • src/lib/runtime-recovery.ts

📝 Walkthrough

Walkthrough

Adds a Ready-phase-aware parser parseReadySandboxNames() and replaces previous phase-agnostic parsing in backup and upgrade flows so only sandboxes with PHASE == "Ready" are considered running; tests added/updated to validate Ready-only selection and that non-Ready sandboxes are skipped during pre-upgrade backup.

Changes

Sandbox backup eligibility fix

Layer / File(s) Summary
Parser and tests
src/lib/runtime-recovery.ts, src/lib/runtime-recovery.test.ts
Adds isNonSandboxRow filtering and parseReadySandboxNames(listOutput?: string) which strips ANSI, ignores headers/errors/mismatch lines, and returns names whose PHASE is exactly "Ready". Tests cover Ready selection, Error exclusion, empty input, and schema-mismatch/error outputs.
Backup & upgrade integration + backup test
src/lib/actions/maintenance.ts, src/lib/actions/gateway-drift-preflight.test.ts, src/lib/actions/upgrade-sandboxes.ts
Replaces uses of parseLiveSandboxNames with parseReadySandboxNames in backupAll() and upgradeSandboxes(). Adds a test asserting backupAll backs up only Ready sandboxes and logs “Skipping '' (not running)” for non-Ready ones.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#4106: Both PRs modify backupAll() handling of sandbox-list output; #4106 changes list capture/retry while this PR changes Ready-only parsing.

Suggested labels

bug, Sandbox, OpenShell

Suggested reviewers

  • ericksoa
  • cv

Poem

🐰 I parsed the list under moonlit beams,

Ready names kept; the broken dreams left beams,
Skipped the Error shells with a gentle hop,
Backups now sail, no installer flop—hip-hop! 🚀

🚥 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 directly and accurately summarizes the main change: updating the pre-upgrade backup loop to skip non-Ready sandboxes instead of attempting backups on all sandboxes.
Linked Issues check ✅ Passed All code changes correctly implement the requirements from issue #4233: parseReadySandboxNames filters to Ready sandboxes only, backup loop skips non-Ready sandboxes, and appropriate tests validate the new behavior.
Out of Scope Changes check ✅ Passed All changes are directly in scope: new parseReadySandboxNames parser, updates to maintenance.ts and upgrade-sandboxes.ts to use it, and comprehensive test coverage for the new functionality.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-4233-backup-skip-non-ready

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.

@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: openshell-gateway-upgrade-e2e, upgrade-stale-sandbox-e2e, sandbox-operations-e2e
Optional E2E: gateway-drift-preflight-e2e, state-backup-restore-e2e

Dispatch hint: openshell-gateway-upgrade-e2e,upgrade-stale-sandbox-e2e,sandbox-operations-e2e

Auto-dispatched E2E: openshell-gateway-upgrade-e2e, upgrade-stale-sandbox-e2e, sandbox-operations-e2e via nightly-e2e.yaml at 86185e7fec3637e71b37b02da841b7de627322e1nightly run

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • openshell-gateway-upgrade-e2e (high): Validates the real OpenShell gateway upgrade path, including that the current installer runs backup-all and reports the old running sandbox was backed up before replacing OpenShell. This directly exercises the changed Ready-only backup selection in a real upgrade flow.
  • upgrade-stale-sandbox-e2e (high): Exercises nemoclaw upgrade-sandboxes --check and stale sandbox rebuild against a real Ready sandbox. This directly covers the changed Ready-only running-set used by upgrade-sandboxes classification.
  • sandbox-operations-e2e (high): Provides broad real sandbox lifecycle coverage, including registry rebuild, process recovery, destroy cleanup, and gateway recovery. runtime-recovery parsing is shared by multiple lifecycle commands, so this is needed as a guard against parser regressions outside the two directly changed commands.

Optional E2E

  • gateway-drift-preflight-e2e (medium): Useful focused regression for backup-all fail-closed behavior when OpenShell sandbox-state RPC output is unsafe or a stale gateway image is detected. The PR touched nearby gateway-drift preflight tests, but the main source changes are Ready parsing rather than drift detection itself.
  • state-backup-restore-e2e (high): Adjacent confidence for backup/restore behavior and sandbox state preservation, though it covers backup-workspace lifecycle rather than the changed backup-all Ready filtering.

New E2E recommendations

  • maintenance backup / Ready-vs-Error sandbox filtering (medium): Existing E2E coverage validates backing up a running sandbox during gateway upgrade, but there is no direct real-flow E2E for backup-all with multiple registered sandboxes where one is Ready and another is Error/Provisioning. The new unit test covers this hermetically, but a real OpenShell phase-mixed regression would not be caught.
    • Suggested test: Add an E2E that creates/registers two sandboxes, forces or simulates one non-Ready OpenShell phase, runs nemoclaw backup-all, and asserts only the Ready sandbox is backed up while the non-Ready sandbox is skipped.
  • sandbox upgrade / non-Ready stale sandbox handling (medium): upgrade-stale-sandbox-e2e covers a Ready stale sandbox, but not the changed behavior that Error/Provisioning sandboxes should be classified as stopped/non-rebuildable rather than rebuilt.
    • Suggested test: Extend or add an upgrade-sandboxes E2E with a stale registered sandbox that appears in OpenShell with a non-Ready phase and assert upgrade-sandboxes --check reports it as stopped/unknown appropriately and does not rebuild it.

Dispatch hint

  • Workflow: nightly-e2e.yaml
  • jobs input: openshell-gateway-upgrade-e2e,upgrade-stale-sandbox-e2e,sandbox-operations-e2e

@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

E2E Scenario Advisor Recommendation

Required scenario E2E: None
Optional scenario E2E: None

Workflow run

Full scenario advisor summary

E2E Scenario Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required scenario E2E

  • None. No scenario workflow, scenario metadata, scenario runtime, or validation-suite files changed.

Optional scenario E2E

  • None.

Relevant changed files

  • None.

@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor

Findings: 0 needs attention, 0 worth checking, 0 nice ideas
Since last review: 1 prior item resolved, 0 still apply, 0 new items found

Workflow run details

This is an automated advisory review. A human maintainer must make the final merge decision.

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/runtime-recovery.ts`:
- Line 46: The current regex /^ (NAME|No sandboxes found\.?$)/i.test(line) is
too broad and can match real sandbox names (e.g., "name-prod"); update the check
in parseLiveSandboxNames to use exact whole-line matches like /^NAME$/i and /^No
sandboxes found\.?$/i (or combine as /^(?:NAME|No sandboxes found\.?)$/i) so
only header/empty-result lines are skipped, and apply the same precise regex
change wherever the original pattern is used to ensure consistency.
🪄 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: 247c4f6c-a50d-4748-8a64-59c566482349

📥 Commits

Reviewing files that changed from the base of the PR and between 9d68966 and d9ef8de.

📒 Files selected for processing (3)
  • src/lib/actions/maintenance.ts
  • src/lib/runtime-recovery.test.ts
  • src/lib/runtime-recovery.ts

Comment thread src/lib/runtime-recovery.ts Outdated
…upgrade-sandboxes

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@cv cv added the v0.0.52 label May 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26477118771
Target ref: 86185e7fec3637e71b37b02da841b7de627322e1
Workflow ref: main
Requested jobs: openshell-gateway-upgrade-e2e,upgrade-stale-sandbox-e2e,sandbox-operations-e2e
Summary: 3 passed, 0 failed, 0 skipped

Job Result
openshell-gateway-upgrade-e2e ✅ success
sandbox-operations-e2e ✅ success
upgrade-stale-sandbox-e2e ✅ success

@cv cv added v0.0.53 and removed v0.0.52 labels May 27, 2026
@ericksoa
ericksoa merged commit 59107b0 into main May 27, 2026
25 checks passed
@wscurran wscurran added bug-fix PR fixes a bug or regression and removed fix labels Jun 3, 2026
@wscurran wscurran added the NV QA Bugs found by the NVIDIA QA Team label Jun 26, 2026
@cv
cv deleted the fix-4233-backup-skip-non-ready branch June 28, 2026 00:21
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 NV QA Bugs found by the NVIDIA QA Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[macOS][Upgrade] Pre-upgrade backup attempts stopped sandboxes instead of skipping — installer aborts before phase [3/3]

4 participants