Skip to content

[Backup/Restore] scripts/backup-workspace.sh restore nests memory/ directory creating wrong path on sandbox (silent data loss) #3555

@hunglp6d

Description

@hunglp6d

Description

scripts/backup-workspace.sh restore reports Restored 6 items successfully, but the memory directory contents are uploaded to a nested path on the sandbox (memory/memory/<file>.md) instead of the expected flat path (memory/<file>.md).

This is silent data loss from a user perspective: backups appear to roundtrip successfully, but daily memory notes end up at an unreachable path that the OpenClaw dashboard / assistant cannot read. The 5 top-level .md files (SOUL/USER/IDENTITY/AGENTS/MEMORY) restore correctly — only the memory/ directory in DIRS=(memory) is affected.

Expected:

  • After restore, /sandbox/.openclaw/workspace/memory/2026-04-20.md exists with original content.

Actual:

  • File ends up at /sandbox/.openclaw/workspace/memory/memory/2026-04-20.md (nested under an extra memory/).
  • Restore output still claims Restored 6 items so users have no signal that something went wrong.

Root cause (best guess):

Asymmetric trailing-slash semantics in openshell sandbox upload. In scripts/backup-workspace.sh:

  • The FILES loop (line ~101) uses src/${f} (no slash)WORKSPACE_PATH/ (slash, parent only) and works correctly.
  • The DIRS loop (line ~111) uses src/${d}/ (slash) → WORKSPACE_PATH/${d}/ (slash, with redundant ${d} in destination), which openshell sandbox upload interprets as "upload directory INTO destination dir" → produces nested memory/memory/.

Detected by: PR #3517 — the new test/e2e/test-state-backup-restore.sh strict MemoryDirRestore assertion catches this consistently. Before #3517, the legacy test-deployment-services.sh SKIPped this case with "Memory directory restore may not be supported" which masked the bug indefinitely.

Reproduction Steps

Easiest path — run the E2E test from PR #3517:

bash test/e2e/test-state-backup-restore.sh

Test reports FAIL TC-STATE-01: MemoryDirRestore — memory/2026-04-20.md does NOT exist on sandbox after restore. Inspect the post-test sandbox to confirm nested path.

Manual reproduction:

  1. Onboard a sandbox: nemoclaw onboard --non-interactive --yes-i-accept-third-party-software
  2. Write a marker into the memory directory:
nemoclaw <sandbox-name> connect
# inside sandbox:
mkdir -p /sandbox/.openclaw/workspace/memory
echo "REPRO_MARKER" > /sandbox/.openclaw/workspace/memory/2026-05-15.md
exit
  1. Back up: bash scripts/backup-workspace.sh backup <sandbox-name>
    → Reports Backup saved to ~/.nemoclaw/backups/<ts>/ (6 items)
  2. Verify host backup correctness:
cat ~/.nemoclaw/backups/<ts>/memory/2026-05-15.md   # → REPRO_MARKER ✓
  1. Destroy sandbox: nemoclaw <sandbox-name> destroy --yes
  2. Re-onboard: nemoclaw onboard --non-interactive --yes-i-accept-third-party-software
  3. Restore: bash scripts/backup-workspace.sh restore <sandbox-name>
    → Reports Restored 6 items to sandbox <sandbox-name> ✓ (claims success)
  4. Inspect sandbox file system:
nemoclaw <sandbox-name> connect
# inside sandbox:
find /sandbox/.openclaw -name '2026-05-15.md'

→ Returns /sandbox/.openclaw/workspace/memory/memory/2026-05-15.md (nested) ❌
→ Expected: /sandbox/.openclaw/workspace/memory/2026-05-15.md

Environment

OS: Ubuntu 24.04.4 LTS (Linux x86_64)
Node.js: v22.22.x (via nvm)
Docker: Docker Engine 27.x
NemoClaw: v0.0.41
OpenShell: 0.0.39

Debug Output

Logs

Checklist

  • I confirmed this bug is reproducible
  • I searched existing issues and this is not a duplicate

Metadata

Metadata

Assignees

Labels

VRDCIssues and PRs submitted by NVIDIA VRDC test team.area: cliCommand line interface, flags, terminal UX, or outputarea: sandboxOpenShell sandbox lifecycle, runtime, config, or recovery

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions