fix(plan): clean up stale worktree branch before re-creating sandbox #10797

Closed
hamza.khyari wants to merge 1 commit from bugfix/m6-sandbox-reexecute-cleanup into master
Member

Summary

Re-executing a plan after a failed attempt or diff review crashed with fatal: a branch named 'cleveragents/plan-<id>' already exists because the worktree branch from the previous execute was never cleaned up.

Fix

Add GitWorktreeSandbox.cleanup_stale() classmethod in the infrastructure layer that idempotently removes stale worktree directories and branches. Each git command has explicit error handling with logging and fallback (manual rmtree if worktree remove fails).

_create_sandbox_for_plan() in the CLI layer delegates to cleanup_stale() before calling sandbox.create().

Changed files

  • src/cleveragents/infrastructure/sandbox/git_worktree.py: +97 lines — new cleanup_stale() classmethod with full error handling
  • src/cleveragents/cli/commands/plan.py: -55 +12 lines — replaced inline subprocess calls with delegation to infrastructure layer
  • features/sandbox_reexecute_cleanup.feature + step file: 3 Behave scenarios
  • CHANGELOG.md: updated

Testing

  • M1 E2E: m1-plan-lifecycle-ok
  • Lint: passes
  • Typecheck: 0 errors
  • 3 Behave scenarios: stale branch removal, idempotency (no branch), create after cleanup

Review feedback addressed (from PR #10000)

Finding Fix
subprocess in CLI layer Moved to GitWorktreeSandbox.cleanup_stale() in infrastructure
import subprocess inside function Top-level import in git_worktree.py
No Behave tests 3 scenarios added
No CHANGELOG Added
Error handling / idempotency Each git command wrapped with explicit error handling + logging
Branch name missing milestone prefix bugfix/m6-sandbox-reexecute-cleanup
plan.py too large Reduced by 43 lines — logic moved to infrastructure

Closes #7271

## Summary Re-executing a plan after a failed attempt or diff review crashed with `fatal: a branch named 'cleveragents/plan-<id>' already exists` because the worktree branch from the previous execute was never cleaned up. ## Fix Add `GitWorktreeSandbox.cleanup_stale()` classmethod in the **infrastructure layer** that idempotently removes stale worktree directories and branches. Each git command has explicit error handling with logging and fallback (manual `rmtree` if `worktree remove` fails). `_create_sandbox_for_plan()` in the CLI layer delegates to `cleanup_stale()` before calling `sandbox.create()`. ## Changed files - `src/cleveragents/infrastructure/sandbox/git_worktree.py`: +97 lines — new `cleanup_stale()` classmethod with full error handling - `src/cleveragents/cli/commands/plan.py`: -55 +12 lines — replaced inline subprocess calls with delegation to infrastructure layer - `features/sandbox_reexecute_cleanup.feature` + step file: 3 Behave scenarios - `CHANGELOG.md`: updated ## Testing - M1 E2E: `m1-plan-lifecycle-ok` - Lint: passes - Typecheck: 0 errors - 3 Behave scenarios: stale branch removal, idempotency (no branch), create after cleanup ## Review feedback addressed (from PR #10000) | Finding | Fix | |---|---| | subprocess in CLI layer | ✅ Moved to `GitWorktreeSandbox.cleanup_stale()` in infrastructure | | import subprocess inside function | ✅ Top-level import in `git_worktree.py` | | No Behave tests | ✅ 3 scenarios added | | No CHANGELOG | ✅ Added | | Error handling / idempotency | ✅ Each git command wrapped with explicit error handling + logging | | Branch name missing milestone prefix | ✅ `bugfix/m6-sandbox-reexecute-cleanup` | | plan.py too large | ✅ Reduced by 43 lines — logic moved to infrastructure | Closes #7271
hamza.khyari added this to the v3.5.0 milestone 2026-04-20 13:23:33 +00:00
fix(plan): clean up stale worktree branch before re-creating sandbox
All checks were successful
CI / build (pull_request) Successful in 3m45s
CI / coverage (pull_request) Successful in 13m29s
CI / helm (pull_request) Successful in 55s
CI / push-validation (pull_request) Successful in 21s
CI / security (pull_request) Successful in 4m22s
CI / e2e_tests (pull_request) Successful in 6m47s
CI / lint (pull_request) Successful in 3m44s
CI / typecheck (pull_request) Successful in 4m15s
CI / quality (pull_request) Successful in 4m20s
CI / integration_tests (pull_request) Successful in 8m4s
CI / unit_tests (pull_request) Successful in 7m3s
CI / docker (pull_request) Successful in 1m29s
CI / status-check (pull_request) Successful in 3s
a9c820610a
When a user re-executes a plan (e.g. after a failed attempt or after
reviewing the diff), _create_sandbox_for_plan crashes with 'fatal: a
branch named cleveragents/plan-<id> already exists' because the
worktree branch from the previous execute was never cleaned up.

Add GitWorktreeSandbox.cleanup_stale() classmethod in the
infrastructure layer that idempotently removes stale worktree
directories and branches.  Each git command has explicit error
handling with logging and fallback (manual rmtree if worktree remove
fails).  _create_sandbox_for_plan in the CLI layer delegates to
cleanup_stale before calling sandbox.create().

ISSUES CLOSED: #7271
hamza.khyari closed this pull request 2026-04-20 13:42:13 +00:00
All checks were successful
CI / build (pull_request) Successful in 3m45s
Required
Details
CI / coverage (pull_request) Successful in 13m29s
Required
Details
CI / helm (pull_request) Successful in 55s
CI / push-validation (pull_request) Successful in 21s
CI / security (pull_request) Successful in 4m22s
Required
Details
CI / e2e_tests (pull_request) Successful in 6m47s
CI / lint (pull_request) Successful in 3m44s
Required
Details
CI / typecheck (pull_request) Successful in 4m15s
Required
Details
CI / quality (pull_request) Successful in 4m20s
Required
Details
CI / integration_tests (pull_request) Successful in 8m4s
Required
Details
CI / unit_tests (pull_request) Successful in 7m3s
Required
Details
CI / docker (pull_request) Successful in 1m29s
Required
Details
CI / status-check (pull_request) Successful in 3s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core!10797
No description provided.