From 75dd808c0ef63589067ffb5e60f06ac94947b2ea Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Wed, 6 May 2026 12:10:53 -0700 Subject: [PATCH 1/2] =?UTF-8?q?fix(desktop):=20prefer=20cloud-confirmed=20?= =?UTF-8?q?v2=20project=20in=20v1=E2=86=92v2=20workspace=20adopt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When multiple host.db rows share a repo_path, the importer's repoPath→v2id map was last-write-wins, so an orphan local project (e.g. left over from a manual repair) could shadow the canonical id. Workspace adopt then called v2Workspace.create with the orphan id and tripped the org-scope check with "Project not found in this organization". Prefer ids that appear as a projectId on the org's cloud workspace list, falling back to first-seen. --- .../ImportWorkspacesPage.tsx | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/ImportWorkspacesPage/ImportWorkspacesPage.tsx b/apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/ImportWorkspacesPage/ImportWorkspacesPage.tsx index ed26b709cf2..245501660f7 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/ImportWorkspacesPage/ImportWorkspacesPage.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/ImportWorkspacesPage/ImportWorkspacesPage.tsx @@ -52,9 +52,19 @@ export function ImportWorkspacesPage({ }); const v2ProjectIdByV1Id = useMemo(() => { + const projectIdsInCloud = new Set( + (cloudWorkspacesQuery.data ?? []).map((w) => w.projectId), + ); const v2ByPath = new Map(); for (const v2 of hostProjectListQuery.data ?? []) { - v2ByPath.set(v2.repoPath, v2.id); + const existing = v2ByPath.get(v2.repoPath); + if (!existing) { + v2ByPath.set(v2.repoPath, v2.id); + continue; + } + if (projectIdsInCloud.has(v2.id) && !projectIdsInCloud.has(existing)) { + v2ByPath.set(v2.repoPath, v2.id); + } } const map = new Map(); for (const v1 of projectsQuery.data ?? []) { @@ -62,7 +72,11 @@ export function ImportWorkspacesPage({ if (v2Id) map.set(v1.id, v2Id); } return map; - }, [hostProjectListQuery.data, projectsQuery.data]); + }, [ + hostProjectListQuery.data, + projectsQuery.data, + cloudWorkspacesQuery.data, + ]); const cloudWorkspaceKeys = useMemo(() => { const set = new Set(); From 24adbb50bee98214881f91d6e82a54d6c67153cb Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Wed, 6 May 2026 12:17:21 -0700 Subject: [PATCH 2/2] fix(desktop): gate v1 import modal on cloud workspace list cloudWorkspacesQuery was missing from isLoading, so a slow cloud response let the modal render Adopt buttons before the preference logic had the signal it needs to skip orphan host.db rows. The preference would then fall back to first-seen and could still pick the orphan, hitting the exact error this PR is meant to prevent. --- .../V1ImportModal/ImportWorkspacesPage/ImportWorkspacesPage.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/ImportWorkspacesPage/ImportWorkspacesPage.tsx b/apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/ImportWorkspacesPage/ImportWorkspacesPage.tsx index 245501660f7..cec6708fdd6 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/ImportWorkspacesPage/ImportWorkspacesPage.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/components/V1ImportModal/ImportWorkspacesPage/ImportWorkspacesPage.tsx @@ -122,6 +122,7 @@ export function ImportWorkspacesPage({ workspacesQuery.isPending || worktreesQuery.isPending || hostProjectListQuery.isPending || + cloudWorkspacesQuery.isPending || worktreeListQueries.some((q) => q.isPending); const [isRefreshing, setIsRefreshing] = useState(false);