Skip to content

fix(cli): orca worktree rm reports the delete's outcome, not its acceptance - #35459

Merged
nwparker merged 1 commit into
mainfrom
fix/35135-worktree-rm-contract
Oct 29, 2026
Merged

nwparker merged 1 commit into
mainfrom
fix/35135-worktree-rm-contract

Conversation

@nwparker

@nwparker nwparker commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 2 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​64 $\color{#cf222e}{\Huge{\mathbf{−}}}$​11 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​53
Prod 5 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​58 $\color{#cf222e}{\Huge{\mathbf{−}}}$​11 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​47

ELI5

orca worktree rm used to say "removed: true" as soon as Orca agreed to delete a workspace, before anything was actually deleted. If the delete then failed, only the host's log knew. The CLI now waits for the real result, so it succeeds when the workspace is gone and fails with Git's error when it isn't.

What Changed

  • Before: the host answers worktree.rm once it accepts the delete, and Git deletes the checkout in the background. The desktop, paired desktop and web clients advertise worktree.background-removal.v1, so the host waits for Git before answering them. The CLI advertises no capabilities, so it got { removed: true, removing: true } right away. A background failure (for example a checkout with submodules) went only to the host's stdout, the CLI exited 0, and every retry silently repeated the failure.
  • After:
    • worktree.rm takes an optional waitForBackgroundRemoval flag. The host waits for Git when the client reads removal markers or sets the flag. This uses the same wait and join paths the desktop already uses.
    • The CLI always sets it, with the same reply timeout the desktop and web clients use (worktreeRemovalReplyTimeoutMs, which also covers --run-hooks). It exits with Git's real result or error. If it stops waiting first, it says the delete may still be running and points at orca worktree show, which lists a failed delete's removalError.
    • A reply sent on acceptance now says removed: false alongside removing: true, so a caller that still gets the early answer (older CLIs, mobile) is never told the checkout is gone. No client reads removed from this reply. I checked the renderer, web, mobile and the skill guides.
    • A new CLI talking to an older host: the older host ignores the flag and answers on acceptance, and the CLI's text output then says removed: false and that the delete is still running.

Why

CLI and automation callers act on the exit status and the JSON reply, so they need the outcome, not acceptance. A "pending" status they would have to poll would push the waiting into every script. The host already keeps waiters for exactly this. The CLI just couldn't ask for it, because the wait was tied to a client capability that also changes how listings look. A per-request flag lets the CLI ask for the outcome without changing what worktree list shows it. Mobile keeps reading acceptance, as it did before.

Linked Issue

Fixes #35135

The submodule refusal itself now happens before teardown in the companion PR #35458.

Thanks to MrClean73 for the detailed report.

Visual Proof

N/A. CLI and RPC behaviour only, with no UI change.

Testing

  • src/main/runtime/rpc/methods/worktree-runtime-routing.test.ts: a capability-less caller that sets the flag gets the wait and receives Git's failure as an RPC error. An accepted, still-running delete replies removed: false. Both fail on origin/main.

  • src/cli/index.test.ts: worktree rm sends the flag with the removal reply timeout and prints removed: false when an older host answers on acceptance. Both fail on origin/main.

  • pnpm check:changed --maxWorkers=2: everything passes except tests unrelated to this change. electron-serve-browser-process fails the same way on origin/main (the real-home write guard). Three cross-version agent-session downgrade tests timed out under machine load and pass when run alone.

  • Not run: a live orca worktree rm against a running desktop or orca serve.

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

Review

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

  • Mixed versions: the new param is optional and older hosts strip it, since the schema is a plain object. Older CLIs on newer hosts get removed: false while a delete is pending, which is accurate.
  • Remote: the flag works over the paired websocket transport too, and the timeout translation covers both transports. SSH hosts run orcad, which uses the same handler.
  • Known gap (not new): if a waiting CLI delete merges in the workspace lifecycle queue into an identical non-waiting delete that is still queued (from mobile), it gets the acceptance reply. The CLI then says the delete is still running, and still never says removed. The desktop has the same gap today.
  • With --json, a new CLI talking to an older host prints that host's reply unchanged (removed: true, removing: true).
  • Mobile parity: mobile still reads acceptance only and does not yet show a failed delete's removalError. That is a separate mobile feature.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Walkthrough

The RPC contract adds an optional parameter for waiting on background worktree removal. The runtime uses client capabilities or the parameter to determine whether to wait, and its reply indicates whether removal is still in progress. The CLI now uses a request helper that configures a timeout and converts runtime timeouts into an in-progress error. CLI and runtime tests cover these responses.

Priority: Normal

Severity of issue fixed: Medium

Merge Risk: Moderate · up to 35389

A fast Git failure can make orca worktree rm report a deletion that did not succeed. Preserve the failure outcome for the waiting CLI before merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: the CLI now reports the worktree deletion outcome instead of only reporting acceptance.
Description check Passed The description includes all required sections, explains the user-visible behavior and implementation, links issue #35135, documents testing and known limitations, and completes the relevant checklist…
Linked Issues check Passed Issue [#35135] requires the CLI removal path to return the Git removal outcome and to avoid reporting completion while removal is pending. requestWorktreeRemoval sends `waitForBackgroundRemoval: tru…
Out of Scope Changes check Passed The changed production files implement the request flag, wait selection, CLI timeout and error handling, and pending-removal response. The changed tests validate these paths. The changes support issue…
Full details: Description check

Explanation

The description includes all required sections, explains the user-visible behavior and implementation, links issue #35135, documents testing and known limitations, and completes the relevant checklist items. It also clearly records tests that were not run and unrelated failures.

Full details: Linked Issues check

Explanation

Issue [#35135] requires the CLI removal path to return the Git removal outcome and to avoid reporting completion while removal is pending. requestWorktreeRemoval sends waitForBackgroundRemoval: true, applies the removal reply timeout, and propagates Git errors. A timeout reports that removal may still be in progress and gives an orca worktree show command. The RPC handler waits when the flag is set and returns removed: false when the result remains removing. The added CLI and RPC tests cover these behaviors.

Full details: Out of Scope Changes check

Explanation

The changed production files implement the request flag, wait selection, CLI timeout and error handling, and pending-removal response. The changed tests validate these paths. The changes support issue [#35135] and do not show unrelated scope.

Full details: Docstring Coverage

Explanation

Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 3 functions across 7 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches: 💡 2
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no new actionable issues were found.

Summary

orca worktree rm now asks the host to wait for the delete result.

  • The CLI waits for Git's result before reporting a worktree removal.
  • Worktree removal replies no longer call an in-progress deletion complete.

nwparker explicitly accepts the existing queue-merging gap, where a waiting caller can share an earlier caller’s acceptance reply. nwparker also acknowledges unchanged JSON from older hosts and defers showing failed deletes on mobile.

Diagram

sequenceDiagram
  participant CLI
  participant Host
  participant Git
  CLI->>Host: "worktree.rm, waitForBackgroundRemoval=true"
  Host->>Git: Delete checkout
  alt Delete succeeds
    Git-->>Host: Complete
    Host-->>CLI: "removed=true"
  else Delete fails
    Git-->>Host: Error
    Host-->>CLI: Error reply
  else CLI times out
    CLI->>CLI: Explain deletion may still be running
  end
Loading

Reviews (2) · Last reviewed commit: "fix(cli): `orca worktree rm` reports the..." · Reviewed by Greptile

…ceptance

The host answers a worktree delete as soon as it accepts it and lets Git
delete the checkout in the background. Clients that show a "removing"
marker ask it to wait for Git, but the CLI could not, so it printed
`removed: true` before anything was deleted, and a delete Git then refused
(for example a checkout with submodules) failed only in the host's log.
Scripts saw success, and every retry repeated the same silent failure.

`worktree.rm` takes an optional `waitForBackgroundRemoval` flag, and the CLI
sets it, so the command exits with Git's real result or error. It waits as
long as the desktop and web clients do and, if it stops waiting first, says
the delete may still be running and how to check. A reply sent on
acceptance now says `removed: false` alongside `removing: true`, so callers
that still get the early answer are not told the checkout is gone. Older
hosts ignore the flag, and the CLI then says the delete is still running.

Fixes #35135
@nwparker
nwparker force-pushed the fix/35135-worktree-rm-contract branch from 6a82f2d to 3538969 Compare October 28, 2026 23:43

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c0f29a83-35bb-4456-9528-2ba1fda03eec
Commits

Reviewing files that changed from the base of the PR and between 4c31ba5 and 3538969.

Files selected for processing: 7
  • src/cli/handlers/worktree-removal-request.ts
  • src/cli/handlers/worktree.ts
  • src/cli/index.test.ts
  • src/main/runtime/rpc/methods/worktree-runtime-routing.test.ts
  • src/main/runtime/rpc/methods/worktree.ts
  • src/main/runtime/rpc/worktree-removal-marker-projection.ts
  • src/shared/rpc-contract/worktree-params.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.

)
return {
removed: true,
removed: result.removing !== true,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Major · Functional Correctness · Heavy lift

Do not infer successful deletion from an absent removing field.

If Git fails before finishAcceptedWorktreeRemoval looks up the pending removal, the settlement code has already deleted that entry. The helper then drops removing without awaiting the failed promise. This line returns removed: true, so orca worktree rm reports success for a failed deletion. Capture the settlement promise when removal is accepted, and await that promise before reporting completion. (raw.githubusercontent.com)

@nwparker
nwparker merged commit 0654de9 into main Oct 29, 2026
70 of 72 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

worktree rm reports removed:true while background removal fails (submodule worktrees), failure only in server log

1 participant