{"record":{"id":"1f7d92bf32d1c29a","repo":"stablyai/orca","slug":"folder-workspaces-do-not-have-local-git-branches","errorCode":null,"errorMessage":"Folder workspaces do not have local Git branches.","messagePattern":"Folder workspaces do not have local Git branches\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ipc/worktrees.ts","lineNumber":3106,"sourceCode":"        worktreeId: string\n        branchName: string\n        expectedHead: string\n        hostId?: ExecutionHostId\n      }\n    ): Promise<ForceDeleteWorktreeBranchResult> => {\n      const { repoId } = parseWorktreeId(args.worktreeId)\n      const cleanupTarget = getPreservedBranchCleanupTarget(\n        args.worktreeId,\n        args.branchName,\n        args.expectedHead,\n        args.hostId\n      )\n      const repo = getRepoForWorktreeRemoval(store, repoId, cleanupTarget.hostId)\n      if (!repo) {\n        throw new Error(`Repo not found: ${repoId}`)\n      }\n      if (isFolderRepo(repo)) {\n        throw new Error('Folder workspaces do not have local Git branches.')\n      }\n\n      if (repo.connectionId) {\n        const provider = requireSshGitProvider(repo.connectionId)\n        // Why: SSH needs the write-capable relay RPC; the read-only git.exec allowlist rejects these worktree/update-ref/config writes.\n        await provider.forceDeletePreservedBranch(\n          repo.path,\n          cleanupTarget.branchName,\n          cleanupTarget.head\n        )\n        await cleanupUnusedWorktreePushTargetRemoteSsh(\n          provider,\n          repo.path,\n          args.worktreeId,\n          cleanupTarget.pushTarget,\n          store\n        )\n      } else {","sourceCodeStart":3088,"sourceCodeEnd":3124,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/worktrees.ts#L3088-L3124","documentation":"Thrown by 'worktrees:forceDeletePreservedBranch' when the resolved repo is a folder workspace (isFolderRepo(repo) is true). Folder workspaces are not git worktrees and have no local git branches, so a force-delete-preserved-branch request is meaningless. The check follows the repo lookup and short-circuits before any git/SSH write path is touched.","triggerScenarios":"Calling forceDeletePreservedBranch on a worktreeId whose repo resolves to a folder workspace, e.g. the user opened a plain folder project and the UI still shows a leftover 'force delete branch' affordance from a previous git worktree session.","commonSituations":"Converting a git project to a folder project but a stale branch-cleanup notification persists. UI component reused across repo types without checking isFolderRepo. Scripted calls iterating all repos without filtering.","solutions":["Suppress the force-delete-branch UI for folder repos (guard with !isFolderRepo(repo)).","If a cleanup badge is stuck, dismiss it client-side rather than invoking the IPC.","Reopen the project as a git worktree if branch management is actually needed."],"exampleFix":"// before\nif (repo) { await forceDeletePreservedBranch(repo, branchName, head) }\n// after\nif (repo && !isFolderRepo(repo)) { await forceDeletePreservedBranch(repo, branchName, head) }","handlingStrategy":"type-guard","validationCode":"if (repo && isFolderRepo(repo)) { hideForceDeleteBranchUI(); return }","typeGuard":"function supportsLocalBranches(repo: Repo): boolean {\n  return !isFolderRepo(repo)\n}","tryCatchPattern":"try { await forceDeletePreservedBranch(repo, branchName, head) }\ncatch (e) {\n  if (/do not have local Git branches/.test(String((e as Error).message))) dismissBranchBadge()\n  else throw e\n}","preventionTips":["Gate branch-management UI on !isFolderRepo(repo).","Filter folder repos out of any batch branch-cleanup iteration.","Reopen as a git worktree if branch operations are required."],"tags":["worktree","folder-workspace","branch-cleanup","validation"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}