Skip to content

[Bug]: Mirror mode with OpenShell >= 0.0.37 creates recursively nested previous-workspace directories in sandbox #96016

Closed

Description

@DaveFan-NCHC

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

  • OpenClaw (@openclaw/openshell-sandbox plugin), behavior confirmed on versions <= 2026.6.6
  • OpenShell backend, versions >= 0.0.37 (released on 2026-05-08)

When mirror is used as the OpenShell sandbox sync mode, the current behavior of the @openclaw/openshell-sandbox plugin appears to package the workspace and synchronize it with the sandbox through upload/download operations.

After the OpenShell upload behavior change introduced in v0.0.37 , this now causes an unexpected side effect: a subdirectory containing the previous sandbox workspace state is created inside the sandbox workspace. After each sync, that subdirectory is nested again, so the directory depth keeps increasing over time.

This does not look like intended behavior.

This appears to be related to the OpenShell upload behavior change introduced by:

Steps to reproduce

  1. Deploy OpenClaw (<= 2026.6.6) with an OpenShell backend (>= 0.0.37), and use the following OpenClaw settings:

    • agents.defaults.sandbox.mode: all
    • agents.defaults.sandbox.backend: openshell
    • agents.defaults.sandbox.workspaceAccess: ro
    • plugins.entries.openshell.config.mode: mirror
  2. Start an agent session.

  3. Ask the agent to create or modify any file in the workspace directory.

  4. Ask the agent to create or modify any file in the workspace directory a second time.

  5. Inspect the agent sandbox workspace directory.

Expected behavior

The sandbox workspace directory should only contain the current workspace contents, such as the expected Markdown files and directories (for example Skills-related directories and other normal workspace files).

It should not accumulate historical copies of the previous workspace state inside itself.

Actual behavior

A directory named after the upload ID appears inside the sandbox workspace directory. Its contents correspond to the previous sandbox workspace state before the latest sync.

After each additional sync, the same pattern repeats and the previous workspace snapshot is nested one level deeper. Over time, the sandbox workspace ends up containing recursively nested historical workspace directories.

In other words, each sync introduces another level of self-nesting, and the directory structure keeps growing in depth.

OpenClaw version

2026.6.6

Operating system

Ubuntu

Install method

k8s

Model

irrelevant

Provider / routing chain

irrelevant

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

No response

Additional information

No response

Activity

  1. clawsweeper commented on Jun 23, 2026

    @clawsweeper
    Contributor

    Thanks for the context here. I did a careful shell check against current main, and this is already implemented.

    Current main fixes the OpenShell mirror self-nesting problem: the upload path no longer sends the generated openclaw-openshell-upload-* staging directory as the remote workspace root, and merged maintainer PR #96303 provides the fix provenance. The latest release still has the old upload shape, so this is fixed on current main only until the next release.

    So I’m closing this as already implemented rather than keeping a duplicate issue open.

    Review details

    Best possible solution:

    Keep the current main OpenShell plugin implementation and let the next release ship the fixed mirror upload behavior.

    Do we have a high-confidence way to reproduce the issue?

    Yes. The old release source uploaded a generated staging directory and upstream OpenShell now preserves named directory basenames; linked PR proof also exercised the behavior against OpenShell v0.0.68, while current main has the corrected upload shape.

    Is this the best way to solve the issue?

    Yes. The current plugin-owned fix avoids uploading the generated staging root and preserves workspace cwd compatibility, which is narrower than the earlier upload . candidate PRs.

    Security review:

    Security review: No PR patch security review applies to this issue cleanup.

    AGENTS.md: found and applied where relevant.

    What I checked:

    • Current main upload shape: Current main stages the local tree under the remote basename, then uploads each staged entry to the managed remote path while keeping the CLI cwd at the workspace; it does not upload the generated staging directory itself. (extensions/openshell/src/backend.ts:750, 3ab8d6aa609a)
    • Mirror sync uses the fixed upload chokepoint: Mirror mode still syncs local workspace content to the remote workspace before exec and back from the remote workspace after exec, so avoiding upload of the staging root addresses the reported compounding path. (extensions/openshell/src/backend.ts:658, 3ab8d6aa609a)
    • Merged fix provenance: Merged PR fix(openshell): make sandbox e2e reliable on current gateway #96303 includes commit 3176e5d, titled fix(openshell): preserve uploaded workspace root, and records real OpenShell E2E proof in its maintainer landing comment. (3176e5db5cff)
    • Current-line history provenance: Local blame on the current checkout ties the implemented upload block to a current-main commit that contains the fixed per-entry staging/upload shape. (extensions/openshell/src/backend.ts:750, 8ecbf83c678c)
    • Release check: The latest release v2026.6.10 was published before the fix and still stages directly into tmpDir, so no release tag contains the current-main proof SHA and this fix is main-only for now. (extensions/openshell/src/backend.ts:743, aa69b12d0086)
    • Upstream OpenShell contract: NVIDIA/OpenShell PRs 952 and 1028 document the dependency behavior change: named directory uploads preserve the basename, while . and file uploads remain flat.

    Likely related people:

    • vincentkoc: Authored merged PR fix(openshell): make sandbox e2e reliable on current gateway #96303, including the fix(openshell): preserve uploaded workspace root commit, and recently touched adjacent OpenShell backend/release surfaces. (role: fix owner and recent area contributor; confidence: high; commits: 3176e5db5cff, 4712df228cad, ce32697250d5; files: extensions/openshell/src/backend.ts, extensions/openshell/src/backend.e2e.test.ts, extensions/openshell/src/backend.types.ts)
    • jacobtomlinson: Historical OpenShell mirror-sync commits hardened the staging/download boundary involved in this bug. (role: mirror sync hardening contributor; confidence: high; commits: 3b9dab0ece46, c02ee8a3a4cb; files: extensions/openshell/src/backend.ts, extensions/openshell/src/mirror.ts, extensions/openshell/src/mirror.test.ts)
    • steipete: Historical commits introduced the OpenShell sandbox backend and remote OpenShell mode that own the affected upload surface. (role: feature introducer; confidence: medium; commits: d8b927ee6a9f, ae7f18e5033d; files: extensions/openshell/src/backend.ts, extensions/openshell/src/config.ts)
    • Shakker: Current checkout blame for the implemented upload block points to this author on the current-main snapshot that contains the fixed upload shape. (role: current line history; confidence: medium; commits: 8ecbf83c678c; files: extensions/openshell/src/backend.ts)

    Codex review notes: model internal, reasoning high; reviewed against 3ab8d6aa609a; fix evidence: commit 3ab8d6aa609a, main fix timestamp 2026-06-25T00:32:29+02:00.

  2. added a commit that references this issue on Jun 23, 2026
    f619ad1
  3. added
    P2Normal backlog priority with limited blast radius.
    impact:otherThis issue has meaningful maintainer-visible impact outside the owned taxonomy.
    issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.
    clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.
    clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.
    clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.
    on Jun 23, 2026
  4. locked as resolved and limited conversation to collaborators on Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.bugSomething isn't workingbug:behaviorIncorrect behavior without a crashclawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:otherThis issue has meaningful maintainer-visible impact outside the owned taxonomy.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions