Repository navigation
fix(db,desktop): cascade host's workspaces on host delete - #5727
Conversation
v2_workspaces_host_fk had no ON DELETE behavior, so deleting a host with remaining workspaces (e.g. undeletable repo-root workspaces on a stale duplicate device) failed with a raw Postgres FK violation surfaced straight into the error toast. Add ON DELETE CASCADE to the FK (migration 0061) and update the delete-host dialog copy, which previously promised workspaces stay.
|
Ready to review this PR? Stage has broken it down into 3 individual chapters for you:
Chapters generated by Stage for commit 1bde5e7 on Jul 17, 2026 1:49am UTC. |
📝 WalkthroughWalkthroughHost deletion now removes associated workspaces through a cascading database relationship. Host settings confirmation text describes removal of the host, access, and workspaces while retaining files on the machine. ChangesHost deletion
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Greptile SummaryThis PR fixes the FK violation that blocked host deletion by adding
Confidence Score: 4/5Safe to merge; the FK fix and dialog copy are correct, with one pre-existing soft-reference gap in automations worth tracking. The core change — adding cascade to the host FK and updating the confirmation dialog — is correct and well-scoped. The only gap is that automations.v2WorkspaceId and automation_runs.v2WorkspaceId are unconstrained UUIDs with no nullification on workspace delete, so they will silently point to deleted rows after a host is removed. This was dormant before (host deletion was always blocked), but this PR makes it reachable in production. packages/db/src/schema/schema.ts — specifically whether automations.v2WorkspaceId and automation_runs.v2WorkspaceId should receive SET NULL FK constraints or be cleaned up by the host-delete handler.
|
| Filename | Overview |
|---|---|
| packages/db/drizzle/0061_v2_workspaces_host_fk_cascade.sql | Drops and re-adds v2_workspaces_host_fk with ON DELETE CASCADE; migration is correct and minimal. |
| packages/db/src/schema/schema.ts | Adds .onDelete("cascade") to v2_workspaces_host_fk — correct fix; however, automations.v2WorkspaceId and automation_runs.v2WorkspaceId are unconstrained UUID columns that will become stale after a cascade workspace delete. |
| apps/desktop/src/renderer/routes/_authenticated/settings/hosts/$hostId/components/HostSettings/components/DeleteHostSection/DeleteHostSection.tsx | Dialog copy accurately updated to reflect that workspaces are now deleted alongside the host; logic is unchanged. |
| packages/db/drizzle/meta/_journal.json | Journal entry for migration 0061 added at the correct index; timestamps and tag are consistent. |
| packages/db/drizzle/meta/0061_snapshot.json | Drizzle-generated schema snapshot for migration 0061; no hand-edits detected. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant UI as Desktop UI
participant API as API / DB
participant PG as Postgres
UI->>API: DELETE /hosts/:hostId
API->>PG: "DELETE FROM v2_hosts WHERE machine_id = ?"
Note over PG: v2_workspaces_host_fk ON DELETE CASCADE (new)
PG-->>PG: "cascade DELETE v2_workspaces WHERE host_id = ?"
Note over PG: chat_sessions.v2_workspace_id → SET NULL ✓
Note over PG: automations.v2_workspace_id → stale UUID (no FK)
Note over PG: automation_runs.v2_workspace_id → stale UUID (no FK)
PG-->>API: OK
API-->>UI: 200 OK
UI->>UI: Navigate to /settings/hosts
UI-->>UI: Toast "Deleted hostName"
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant UI as Desktop UI
participant API as API / DB
participant PG as Postgres
UI->>API: DELETE /hosts/:hostId
API->>PG: "DELETE FROM v2_hosts WHERE machine_id = ?"
Note over PG: v2_workspaces_host_fk ON DELETE CASCADE (new)
PG-->>PG: "cascade DELETE v2_workspaces WHERE host_id = ?"
Note over PG: chat_sessions.v2_workspace_id → SET NULL ✓
Note over PG: automations.v2_workspace_id → stale UUID (no FK)
Note over PG: automation_runs.v2_workspace_id → stale UUID (no FK)
PG-->>API: OK
API-->>UI: 200 OK
UI->>UI: Navigate to /settings/hosts
UI-->>UI: Toast "Deleted hostName"
Comments Outside Diff (1)
-
packages/db/src/schema/schema.ts, line 779 (link)Stale
v2WorkspaceIdin automations after host deleteautomations.v2WorkspaceIdandautomation_runs.v2WorkspaceId(line 825) hold workspace IDs with no FK constraint — they are bareuuid()columns with no.references()call.chat_sessions.v2WorkspaceIdis correctly handled withonDelete: "set null", but automations and automation_runs are not. When a host is deleted, its workspace rows cascade-delete (the fix this PR introduces), leaving these two columns pointing to deleted workspace IDs. Any app code that looks up a workspace byautomations.v2WorkspaceIdorautomation_runs.v2WorkspaceIdwill get a missing row without any nullification signal from the DB.Prompt To Fix With AI
This is a comment left during a code review. Path: packages/db/src/schema/schema.ts Line: 779 Comment: **Stale `v2WorkspaceId` in automations after host delete** `automations.v2WorkspaceId` and `automation_runs.v2WorkspaceId` (line 825) hold workspace IDs with no FK constraint — they are bare `uuid()` columns with no `.references()` call. `chat_sessions.v2WorkspaceId` is correctly handled with `onDelete: "set null"`, but automations and automation_runs are not. When a host is deleted, its workspace rows cascade-delete (the fix this PR introduces), leaving these two columns pointing to deleted workspace IDs. Any app code that looks up a workspace by `automations.v2WorkspaceId` or `automation_runs.v2WorkspaceId` will get a missing row without any nullification signal from the DB. How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
packages/db/src/schema/schema.ts:779
**Stale `v2WorkspaceId` in automations after host delete**
`automations.v2WorkspaceId` and `automation_runs.v2WorkspaceId` (line 825) hold workspace IDs with no FK constraint — they are bare `uuid()` columns with no `.references()` call. `chat_sessions.v2WorkspaceId` is correctly handled with `onDelete: "set null"`, but automations and automation_runs are not. When a host is deleted, its workspace rows cascade-delete (the fix this PR introduces), leaving these two columns pointing to deleted workspace IDs. Any app code that looks up a workspace by `automations.v2WorkspaceId` or `automation_runs.v2WorkspaceId` will get a missing row without any nullification signal from the DB.
Reviews (1): Last reviewed commit: "fix(db,desktop): cascade host's workspac..." | Re-trigger Greptile
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/db/src/schema/schema.ts (1)
576-576: 🗄️ Data Integrity & Integration | 🔵 Trivial | 🏗️ Heavy liftAdd DB-backed coverage for the host-delete cascade. The mocked router test only covers the SQL call, so it can’t catch a broken
v2_hosts -> v2_workspaces -> chat_sessionscascade. Assert that deleting a host removes its workspaces and sets linkedchat_sessions.v2_workspace_idto null.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/db/src/schema/schema.ts` at line 576, Add database-backed test coverage for the host deletion cascade defined by the schema relation. Insert a host with associated workspaces and linked chat sessions, delete the host through the database, then assert the workspaces are removed and each affected chat_sessions.v2_workspace_id is null; keep the existing mocked router test unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/db/src/schema/schema.ts`:
- Line 576: Add database-backed test coverage for the host deletion cascade
defined by the schema relation. Insert a host with associated workspaces and
linked chat sessions, delete the host through the database, then assert the
workspaces are removed and each affected chat_sessions.v2_workspace_id is null;
keep the existing mocked router test unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 7d7be529-c924-49b4-9e60-d2045c7b0ee2
📒 Files selected for processing (5)
apps/desktop/src/renderer/routes/_authenticated/settings/hosts/$hostId/components/HostSettings/components/DeleteHostSection/DeleteHostSection.tsxpackages/db/drizzle/0061_v2_workspaces_host_fk_cascade.sqlpackages/db/drizzle/meta/0061_snapshot.jsonpackages/db/drizzle/meta/_journal.jsonpackages/db/src/schema/schema.ts
🧹 Preview Cleanup CompleteThe following preview resources have been cleaned up:
Thank you for your contribution! 🎉 |
Problem
Deleting a host from Settings → Hosts fails whenever the host still owns workspace rows.
v2_workspaces_host_fkwas defined without anonDeleteclause (defaults toNO ACTION), so theDELETE FROM v2_hostsinv2Host.deleteis rejected by Postgres and the raw FK-violation message lands in the error toast.This is unavoidable for stale duplicate devices: repo-root (
main) workspaces can't be deleted through the normal workspace-delete action, so they pin the dead host forever.Reported by a user (support, 2026-07-16) with a stale host left behind by an uninstalled build; they confirmed cascade-deleting the dead host's workspaces is the desired behavior.
Fix
.onDelete("cascade")tov2_workspaces_host_fk(matches the existing cascade onv2_users_hosts_host_fk). Migration0061_v2_workspaces_host_fk_cascadedrops and re-adds the constraint.Downstream is safe:
chat_sessions.v2_workspace_idisSET NULL, and nothing else hard-referencesv2_workspaces.Notes
drizzle-kit generate; no hand-edits topackages/db/drizzle/.Verification
bun run typecheckpasses; Biome clean on changed files.bun run lintcurrently fails on unrelated pre-existing nested.conductor/*Biome root configs, not on this change.Summary by cubic
Fixes host deletion by cascading the host’s
v2_workspaceson delete. Updates the desktop delete-host dialog to clarify that the host’s workspaces are removed and files on the machine stay.0061_v2_workspaces_host_fk_cascadebefore shipping desktop; it recreatesv2_workspaces_host_fkwith ON DELETE CASCADE.chat_sessions.v2_workspace_iduses SET NULL.Written for commit 1bde5e7. Summary will update on new commits.
Summary by CodeRabbit
User Experience
Bug Fixes