fix(plugins): stage git plugin clone on target filesystem to avoid EXDEV#99896
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 5, 2026, 12:34 AM ET / 04:34 UTC. Summary PR surface: Source +38, Tests +128. Total +166 across 4 files. Reproducibility: yes. Current main stages git clones under os.tmpdir() and then uses a rename-only directory replacement into the managed git repo, which source-proves the EXDEV path when those roots are on different filesystems; I did not rerun a live Docker repro in this read-only review. Review metrics: none identified. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Next step before merge
Security Review detailsBest possible solution: Land the same-filesystem staging fix after current-head CI completes, preserving dry-run ephemerality and the existing atomic replacement primitive. Do we have a high-confidence way to reproduce the issue? Yes. Current main stages git clones under os.tmpdir() and then uses a rename-only directory replacement into the managed git repo, which source-proves the EXDEV path when those roots are on different filesystems; I did not rerun a live Docker repro in this read-only review. Is this the best way to solve the issue? Yes. Same-filesystem staging is the narrowest maintainable fix because it keeps the existing atomic replacement semantics instead of adding a broader copy fallback to the git publish path. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against e069cb26f72a. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +38, Tests +128. Total +166 across 4 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (9 earlier review cycles; latest 8 shown)
|
|
@clawsweeper re-review — the PR body already includes redacted real behavior proof for the exact reported scenario: a stage-then- |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review — the requested real behavior proof is already in the PR body under "Real behavior proof (cross-filesystem rename)". It's a redacted terminal transcript reproducing the exact failure and fix on two genuinely distinct filesystems (managed git root on a separate APFS volume vs
This exercises the same stage-then- |
b8e86a1 to
aea559f
Compare
|
🦞🧹 I asked ClawSweeper to review this item again. |
2b5f160 to
f2cdc7a
Compare
Git plugin installs cloned into os.tmpdir() then atomically renamed the staged repo into ~/.openclaw/git/. When /tmp and the state dir live on different filesystems (common in Docker with bind-mounted volumes), the rename failed with EXDEV: cross-device link not permitted. Stage the clone under the managed git root (same filesystem as the destination) so the final rename never crosses devices. Falls back to os.tmpdir() when the managed root cannot be prepared, preserving prior behavior. Closes openclaw#99885
573cedb to
7f51687
Compare
7f51687 to
43ca9a0
Compare
|
Merged via squash.
|
…DEV (openclaw#99896) * fix(plugins): stage git plugin clone on target filesystem to avoid EXDEV Git plugin installs cloned into os.tmpdir() then atomically renamed the staged repo into ~/.openclaw/git/. When /tmp and the state dir live on different filesystems (common in Docker with bind-mounted volumes), the rename failed with EXDEV: cross-device link not permitted. Stage the clone under the managed git root (same filesystem as the destination) so the final rename never crosses devices. Falls back to os.tmpdir() when the managed root cannot be prepared, preserving prior behavior. Closes openclaw#99885 * fix(plugins): isolate git clone staging per install --------- Co-authored-by: Vincent Koc <[email protected]>
What Problem This Solves
Git-backed plugin installs cloned into
os.tmpdir()and then published themanaged repository with an atomic rename into the OpenClaw state directory.
When those paths were on different filesystems, the rename failed with
EXDEV: cross-device link not permittedand the install aborted.Fixes #99885.
Why This Change Was Made
Non-dry-run clones now use a private temporary workspace beside the exact
managed
git-<hash>/repotarget. The staged clone and the rename targettherefore share a filesystem, preserving atomic replacement without adding a
copy fallback to the shared filesystem primitive.
withTempDiraccepts an optional root for this owner-controlled staging path.Dry runs deliberately keep the default OS temp workspace so validation remains
ephemeral and does not create managed state. If the target parent cannot be
prepared, the existing structured managed-repository replacement error path is
preserved. Workspace initialization fallback happens only before the clone
callback starts, so clone and dependency-install side effects are never retried.
User Impact
openclaw plugins install git:<repo>and git-backed plugin updates now workwhen the OpenClaw state directory is mounted separately from
/tmp, includingcommon container and bind-mount layouts. Existing install policy, dependency
scan, URL redaction, and atomic replacement behavior are unchanged.
Evidence
source, install directory, replace file, and CLI install.
pnpm check:changedpassed core/core-test typecheck,lint, import cycles, and policy guards.
temp-helper importer (83 tooling tests).
64768and OpenClaw stateplus the managed clone on device
21.