Skip to content

fix(desktop): improve teardown and delete error handling with diagnostic logging - #1217

Merged
Kitenite merged 4 commits into
mainfrom
kitenite/fix/teardown-error-handling
Feb 5, 2026
Merged

Kitenite merged 4 commits into
mainfrom
kitenite/fix/teardown-error-handling

Conversation

@Kitenite

@Kitenite Kitenite commented Feb 5, 2026 •

Copy link
Copy Markdown
Member

Fixes #1178

Summary

  • Block deletion on teardown failure: Both delete (active workspace) and deleteWorktree (closed worktree) now abort and return an error if teardown scripts fail, instead of silently proceeding with worktree removal
  • Extract removeWorktreeFromDisk helper: Shared helper deduplicates the git worktree removal + error handling logic across both deletion paths
  • Teardown script: Surface Neon branch deletion failures instead of silently swallowing errors (2>/dev/null removed, warn → error + return 1)
  • Delete procedure: Add diagnostic logging when teardown is skipped or not needed

Type of Change

  • Bug fix

Testing

  • Delete a workspace with a working teardown → succeeds normally
  • Delete a workspace where teardown fails → deletion aborts, workspace remains, user sees error
  • Delete a workspace with no .superset/config.json → succeeds (no teardown = success)
  • Delete a hidden worktree with same scenarios
  • Verify teardown.sh returns non-zero on failure

Summary by CodeRabbit

Bug Fixes

  • Deletion operations now surface errors (non-zero exit) and present clearer failure messages when branch or workspace removal fails.
  • Worktree and workspace teardown reliably report success/failure, log diagnostic details, and prevent silent failures.
  • UI rollback restored on failed deletes: optimistic updates are reverted and navigation/state are preserved when removal fails.
  • Delete dialogs and toasts now display actual backend results and any terminal warnings.

@coderabbitai

coderabbitai Bot commented Feb 5, 2026 •

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Removed stderr suppression in the Neon branch-delete script, made branch-delete failures exit with code 1, and refactored workspace deletion to use a new removeWorktreeFromDisk helper plus structured teardown results and additional diagnostic logging; deletion flows now propagate teardown errors.

Changes

Cohort / File(s) Summary
Teardown script
/.superset/teardown.sh
Removed stderr suppression from neonctl branches delete, converted deletion failures into errors that cause the script to exit with code 1.
Workspace delete procedure
apps/desktop/src/lib/trpc/routers/workspaces/procedures/delete.ts
Replaced direct worktree removal with removeWorktreeFromDisk; await teardown alongside terminal kills, check structured { success, error }, log and return on teardown failure.
Teardown utilities
apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts
Added exported removeWorktreeFromDisk wrapper around git removal, improved runTeardown diagnostics for no-teardown cases, and return structured success/error objects.
Frontend mutation & dialogs
apps/desktop/src/renderer/react-query/workspaces/useDeleteWorkspace.ts, apps/desktop/src/renderer/screens/.../DeleteWorkspaceDialog.tsx, apps/desktop/src/renderer/screens/.../DeleteWorktreeDialog.tsx
Mutation onSuccess now accepts context and rolls back optimistic updates when deletion fails; dialog flows validate mutation result shape and throw on { success: false } to surface errors via toasts.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant TRPC as "TRPC delete.ts"
    participant Terminals as "Terminal Manager"
    participant Teardown as "teardown.ts"
    participant Git as "git / neonctl"

    Client->>TRPC: request delete workspace
    TRPC->>Terminals: kill terminals (parallel)
    Terminals-->>TRPC: killed / warnings
    TRPC->>Teardown: runTeardown(workspace) & removeWorktreeFromDisk
    Teardown->>Git: run teardown commands / neonctl/removeWorktree
    Git-->>Teardown: {success:true} or {success:false, error}
    Teardown-->>TRPC: structured teardown result
    TRPC-->>Client: return success or propagate error (on teardown failure)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰
I hopped where scripts once silenced cries,
Now branches shout beneath the skies.
Teardowns whisper true or wrong,
I hum a tidy, brambly song.
Clean hops onward, ledger strong.

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: improving error handling for teardown with diagnostic logging in desktop deletion workflows.
Description check ✅ Passed The description includes all required sections: Summary with clear bullet points, Related Issues linked to #1178, Type of Change marked as Bug fix, and comprehensive Testing scenarios.
Linked Issues check ✅ Passed The PR fully addresses #1178 by implementing teardown script execution and treating teardown failures as abort conditions for deletion, preventing silent worktree removal.
Out of Scope Changes check ✅ Passed All changes align with the core objectives: teardown error handling improvements, worktree removal extraction, script failure surfacing, and diagnostic logging. No unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch kitenite/fix/teardown-error-handling

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 and usage tips.

@github-actions

github-actions Bot commented Feb 5, 2026 •

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

🔗 Preview Links

Service Status Link
Neon Database (Neon) ✅ View Branch
Fly.io Electric (Fly.io) ✅ View App
Vercel API (Vercel) ✅ Open Preview
Vercel Web (Vercel) ✅ Open Preview
Vercel Marketing (Vercel) ✅ Open Preview
Vercel Admin (Vercel) ✅ Open Preview
Vercel Docs (Vercel) ✅ Open Preview

Preview updates automatically with new commits

@Kitenite Kitenite changed the title Update delete and teardown script fix(desktop): improve teardown and delete error handling with diagnostic logging Feb 5, 2026

@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

🤖 Fix all issues with AI agents
In `@apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts`:
- Around line 47-50: The log message incorrectly reports "found, no teardown
field" even when config.teardown exists but is empty; update the block that
checks if (!config?.teardown || config.teardown.length === 0) to compute a clear
reason string (e.g., "config not found", "config found, teardown field missing",
or "config found, teardown field empty") and include that reason in the
console.log; reference the existing variables config, config.teardown,
workspaceName, mainRepoPath and the current console.log call in teardown.ts to
implement this clearer diagnostic.
🧹 Nitpick comments (3)
apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts (1)

146-170: Prefix removeWorktreeFromDisk logs with a context tag.

The warning/error logs here are missing a [domain/operation] prefix.

🪵 Suggested logging prefix
-			console.warn(
-				`Worktree ${worktreePath} not found in git, skipping removal`,
-			);
+			console.warn(
+				`[teardown/removeWorktree] Worktree ${worktreePath} not found in git, skipping removal`,
+			);
 			return { success: true };
 		}
-		console.error("Failed to remove worktree:", msg);
+		console.error(`[teardown/removeWorktree] Failed to remove worktree: ${msg}`);
As per coding guidelines: Use prefixed console logging with consistent context pattern: [domain/operation] message for entry/exit of significant operations, external API calls, and error conditions.
apps/desktop/src/lib/trpc/routers/workspaces/procedures/delete.ts (2)

200-240: Consider extracting teardown orchestration and switching runTeardown to an options object.

This mutation is already large; pulling the teardown/cleanup orchestration into a helper would keep the tRPC procedure thinner. Also, switching runTeardown to an options object reduces positional-parameter ordering risks.

♻️ Suggested refactor (options object)
diff --git a/apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts b/apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts
@@
-export async function runTeardown(
-	mainRepoPath: string,
-	worktreePath: string,
-	workspaceName: string,
-): Promise<TeardownResult> {
+export async function runTeardown({
+	mainRepoPath,
+	worktreePath,
+	workspaceName,
+}: {
+	mainRepoPath: string;
+	worktreePath: string;
+	workspaceName: string;
+}): Promise<TeardownResult> {
 	const config = loadSetupConfig(mainRepoPath);
diff --git a/apps/desktop/src/lib/trpc/routers/workspaces/procedures/delete.ts b/apps/desktop/src/lib/trpc/routers/workspaces/procedures/delete.ts
@@
-						teardownPromise = runTeardown(
-							project.mainRepoPath,
-							worktree.path,
-							workspace.name,
-						);
+						teardownPromise = runTeardown({
+							mainRepoPath: project.mainRepoPath,
+							worktreePath: worktree.path,
+							workspaceName: workspace.name,
+						});
@@
-						const teardownResult = await runTeardown(
-							project.mainRepoPath,
-							worktree.path,
-							worktree.branch,
-						);
+						const teardownResult = await runTeardown({
+							mainRepoPath: project.mainRepoPath,
+							worktreePath: worktree.path,
+							workspaceName: worktree.branch,
+						});
As per coding guidelines: Use object parameters for functions with 2 or more parameters instead of positional arguments. Based on learnings: Extract business logic from tRPC procedures when: the procedure exceeds ~50 lines of non-trivial logic, the same logic is needed by multiple procedures, complex error handling exists, or you need to mock the logic independently for testing.

428-447: Add a prefixed context to the missing-worktree warning.

The new warning should include the standard [domain/operation] prefix for consistency with other logs in this file.

🪵 Suggested logging prefix
-					console.warn(
-						`Worktree ${worktree.path} not found in git, skipping removal`,
-					);
+					console.warn(
+						`[workspace/deleteWorktree] Worktree ${worktree.path} not found in git, skipping removal`,
+					);
As per coding guidelines: Use prefixed console logging with consistent context pattern: [domain/operation] message for entry/exit of significant operations, external API calls, and error conditions.

Comment on lines 47 to +50
if (!config?.teardown || config.teardown.length === 0) {
console.log(
`[teardown] No teardown commands found for "${workspaceName}" (config: ${config ? "found, no teardown field" : "not found"}, mainRepoPath: ${mainRepoPath})`,
);

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.

⚠️ Potential issue | 🟡 Minor

Clarify the config state in the no-teardown log.

When config.teardown exists but is empty, the message still says “no teardown field,” which can mislead diagnostics.

✅ Suggested tweak
-		console.log(
-			`[teardown] No teardown commands found for "${workspaceName}" (config: ${config ? "found, no teardown field" : "not found"}, mainRepoPath: ${mainRepoPath})`,
-		);
+		const configStatus = !config
+			? "not found"
+			: config.teardown
+				? "found, teardown empty"
+				: "found, no teardown field";
+		console.log(
+			`[teardown] No teardown commands found for "${workspaceName}" (config: ${configStatus}, mainRepoPath: ${mainRepoPath})`,
+		);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!config?.teardown || config.teardown.length === 0) {
console.log(
`[teardown] No teardown commands found for "${workspaceName}" (config: ${config ? "found, no teardown field" : "not found"}, mainRepoPath: ${mainRepoPath})`,
);
if (!config?.teardown || config.teardown.length === 0) {
const configStatus = !config
? "not found"
: config.teardown
? "found, teardown empty"
: "found, no teardown field";
console.log(
`[teardown] No teardown commands found for "${workspaceName}" (config: ${configStatus}, mainRepoPath: ${mainRepoPath})`,
);
🤖 Prompt for AI Agents
In `@apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts` around lines
47 - 50, The log message incorrectly reports "found, no teardown field" even
when config.teardown exists but is empty; update the block that checks if
(!config?.teardown || config.teardown.length === 0) to compute a clear reason
string (e.g., "config not found", "config found, teardown field missing", or
"config found, teardown field empty") and include that reason in the
console.log; reference the existing variables config, config.teardown,
workspaceName, mainRepoPath and the current console.log call in teardown.ts to
implement this clearer diagnostic.

This branch was previously deployed

1 inactive deployment
preview — d7fb6d62 Deployed Feb 5, 2026 by Kitenite via Deploy Marketing #1528
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.

[bug] Teardown scripts do not run

1 participant