stablyai/orca · error · Error
Cannot delete the project root workspace. Remove the folder
Error message
Cannot delete the project root workspace. Remove the folder project instead.
What it means
Thrown by both worktrees:remove and worktrees:forgetLocal when the target worktreeId equals the folder workspace root id (getFolderWorkspaceRootId). Folder workspaces share a single root directory; deleting it would destroy the project itself, so removal is blocked and the user is told to remove the folder project instead.
Source
Thrown at src/main/ipc/worktrees.ts:2385
// The resolved repo supplies host ownership when legacy callers omit args.hostId.
const removalHostId = getRepoExecutionHostId(repo)
const inFlightKey = getWorktreeRemovalInFlightKey(args.worktreeId, removalHostId)
const optionsKey = getWorktreeRemovalOptionsKey(args)
const inFlightRemoval = worktreeRemovalsInFlight.get(inFlightKey)
if (inFlightRemoval) {
if (inFlightRemoval.optionsKey === optionsKey) {
return inFlightRemoval.promise
}
throw new Error(`Worktree deletion already in progress: ${args.worktreeId}`)
}
// Why: concurrent stale-toast/double-click/sidebar races can hit the same worktree; share the op so only one path touches Git and disk.
const removal = (async (): Promise<RemoveWorktreeResult> => {
// Why: worktree.create is traced; delete freezes were invisible without a matching worktree.remove parent span.
return withWorktreeSpan({ stage: 'remove', path: worktreePath }, async () => {
if (isFolderRepo(repo)) {
if (args.worktreeId === getFolderWorkspaceRootId(repo)) {
throw new Error(
'Cannot delete the project root workspace. Remove the folder project instead.'
)
}
// Why: folder workspaces share one root, so there's no Git remove step to close shells; sweep PTYs before dropping metadata.
await withWorktreeRemoveStageSpan('pty_sweep', 'folder', async () => {
// Folder projects can be SSH-backed, so fence the sweep to the owning host exactly
// like the git paths — the local inventory must never reach a remote workspace's id.
// The resolved repo is authoritative here: path-derived metadata is shared by
// same-id host copies and can describe a different owner's workspace.
const ownerHost = parseExecutionHostId(removalHostId)
const sshPtyProvider =
ownerHost?.kind === 'ssh' ? getSshPtyProvider(ownerHost.targetId) : undefined
const externalHost = ownerHost?.kind === 'ssh' || ownerHost?.kind === 'runtime'
await killAllProcessesForWorktree(args.worktreeId, {
runtime,
resolvedWorktreeId: args.worktreeId,
...(ownerHost?.kind === 'ssh' ? { resolvedConnectionId: ownerHost.targetId } : {}),
...(ownerHost?.kind === 'runtime'View on GitHub (pinned to 1136503c6a)
Solutions
- Hide/disable delete for the folder root workspace in the UI and route project removal through the folder-project removal flow.
- For automation, detect folder repos and never call remove on getFolderWorkspaceRootId(repo).
- If the user wants the workspace gone, remove the folder project via its dedicated removal API.
Defensive patterns
Strategy: validation
Validate before calling
import { isFolderRepo } from '../../shared/folder-workspaces'
import { getFolderWorkspaceRootId } from '../../shared/folder-workspace-id'
function canDeleteWorktree(repo, worktreeId) {
return !(isFolderRepo(repo) && worktreeId === getFolderWorkspaceRootId(repo))
} Type guard
function isFolderRootWorkspace(repo: unknown, worktreeId: string): boolean {
return !!repo && isFolderRepo(repo) && worktreeId === getFolderWorkspaceRootId(repo)
} Prevention
- Never offer delete on the folder root workspace row.
- Route folder-project removal through its dedicated API.
- For automation, detect folder repos and exclude their root id from remove calls.
When it happens
Trigger: Issuing worktrees:remove or worktrees:forgetLocal with the folder project's root workspace id for a folder-mode repo (isFolderRepo true).
Common situations: UI inadvertently offers a delete action on the folder root row, or a remote/automation client targets the root id of a folder workspace.
Related errors
- Repo not found: ${repoId}
- Selected file is not a markdown document.
- ${label} is required
- ${label} is required
- Cannot download to a directory
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/0e8ee5f088e4f0b1.
Report an issue: GitHub.