Repository navigation
Skill --force install rolls back after leftover backup delete fails #3733
Copy link
Copy link
Closed
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:bulk-filedClawSweeper detected a high recent issue-filing volume from this author.ClawSweeper detected a high recent issue-filing volume from this author.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:ux-frictionUser-facing flow adds avoidable confusion or support burden without fully blocking progress.User-facing flow adds avoidable confusion or support burden without fully blocking progress.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Description
What happens
clawhub skill install --force (and update) stages the new tree, swaps it into place, then deletes the old backup. That last delete sits in the same try as the swap. force: true only swallows a missing path. If delete throws EBUSY or EPERM (Windows antivirus, a locked file), the catch removes the new install and restores the backup.
The upgrade already succeeded. Cleanup of the leftover backup then undoes it.
How to see it
- Install a skill so the target directory exists.
- Run
clawhub skill install <slug> --force. - If deleting
.slug.backup-*fails after the swap, the command errors and the previous tree is restored.
From the code: installSkillWithOptionalStaging in packages/clawhub/src/cli/commands/skills.ts. Introduced in 7d69b337c7a7 (fix: make skill updates rollback safe).
Expected
Once the new tree is in place, backup delete is best-effort. A leftover backup directory is fine. Rolling back a finished swap is not.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:bulk-filedClawSweeper detected a high recent issue-filing volume from this author.ClawSweeper detected a high recent issue-filing volume from this author.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:ux-frictionUser-facing flow adds avoidable confusion or support burden without fully blocking progress.User-facing flow adds avoidable confusion or support burden without fully blocking progress.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Priority
None yet
Activity
SebTardif commentedon Sep 16, 2026
Opened PR #3734 for this tracker (
Refonly).clawsweeper commentedon Sep 16, 2026
Codex review: keeping this open for maintainer follow-up; there is still a little grit to resolve. Reviewed September 20, 2026, 10:36 AM ET / 14:36 UTC.
Summary
The defect remains on current main and in v0.23.3. The reporter’s open fix PR already covers this repair, so the issue remains necessary.
Reproducibility: yes. from source: make backup deletion reject after both renames succeed, and the catch removes the replacement and restores the old tree. No runtime reproduction was executed.
Next step
Review the existing candidate at #3734; the paired PR and bulk-filer signal exclude another automated repair dispatch.
Review details
Best possible solution:
Treat successful replacement as the rollback boundary, make subsequent backup cleanup best-effort, and preserve recovery for failures before replacement completes.
Do we have a high-confidence way to reproduce the issue?
Yes, from source: make backup deletion reject after both renames succeed, and the catch removes the replacement and restores the old tree. No runtime reproduction was executed.
Is this the best way to solve the issue?
Yes, separating post-swap cleanup from rollback is the narrowest repair in the shared helper; filesystem retries alone would still allow eventual cleanup failure to undo success.
AGENTS.md: found and applied where relevant.
Remaining risk / open question:
Codex review notes: model internal, reasoning medium; reviewed against ff6c118c132a.
Label changes
Label justifications:
P2: A backup cleanup error can undo a completed skill replacement; the demonstrated scope is an existing-install CLI workflow.impact:ux-friction: Users receive an installation error and retain the old version after the replacement itself succeeded.Evidence reviewed
What I checked:
packages/clawhub/src/cli/commands/skills.ts:1848, ff6c118c132a)packages/clawhub/src/cli/commands/skills.ts:1122, ff6c118c132a)packages/clawhub/src/cli/commands/skills.ts,87ca030c30f3cfb78ab15c8e66b5ff1469c8f9c8f9c8)packages/clawhub/src/cli/commands/skills.ts, 7d69b337c7a7)Likely related people:
How this review workflow works
@clawsweeper re-reviewcomments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.@clawsweeper re-reviewor@clawsweeper re-runon an open PR or issue to request a fresh review only.@clawsweeper reviewto request a fresh review only.@clawsweeper autofix,@clawsweeper automerge,@clawsweeper fix ci, or@clawsweeper address review.@clawsweeper explainto ask for more context, or@clawsweeper stopto stop active automation.steipete commentedon Sep 30, 2026
Fixed on main by #3853 (d26329b), completing @SebTardif's #3734 with contributor credit preserved. Successful replacement is now the rollback boundary; failure to remove the old backup leaves the new files and matching lockfile installed.
The Linux regression runs the built Node CLI against a synthetic loopback registry with real ZIP extraction and filesystem operations, injecting EBUSY only for backup removal. It failed on unchanged main; afterward all 22 artifact tests pass, including new content, lockfile version, and retained backup assertions. Static, full coverage (7,250 passed, 3 skipped), package, type/build, and HTTP gates passed, as did exact-head CI.
A CLI release containing this commit is still required.
fix: keep completed skill installs when backup cleanup fails (opencla…