{"record":{"id":"866ed670ff35f65a","repo":"gitbutlerapp/gitbutler","slug":"failed-to-add-project-after-cloning","errorCode":null,"errorMessage":"Failed to add project after cloning.","messagePattern":"Failed to add project after cloning\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/desktop/src/components/onboarding/CloneForm.svelte","lineNumber":90,"sourceCode":"\n\t\ttry {\n\t\t\tconst remoteUrl = parseRemoteUrl(repositoryUrl);\n\t\t\tif (!remoteUrl) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst targetDir = await backend.joinPath(targetDirPath, remoteUrl.name);\n\n\t\t\tawait gitService.cloneRepo(repositoryUrl, targetDir);\n\n\t\t\tposthog.captureOnboarding(OnboardingEvent.ClonedProject);\n\t\t\tconst outcome = await projectsService.addProject(targetDir);\n\t\t\tif (!outcome) {\n\t\t\t\tposthog.captureOnboarding(\n\t\t\t\t\tOnboardingEvent.ClonedProjectFailed,\n\t\t\t\t\t\"Failed to add project after cloning\",\n\t\t\t\t);\n\t\t\t\tthrow new Error(\"Failed to add project after cloning.\");\n\t\t\t}\n\n\t\t\thandleAddProjectOutcome(outcome, (project) => goto(projectPath(project.id)));\n\t\t} catch (e) {\n\t\t\tSentry.captureException(e);\n\t\t\tconst errorMessage = getErrorMessage(e);\n\t\t\tposthog.captureOnboarding(OnboardingEvent.ClonedProjectFailed, e);\n\t\t\terrors.push({\n\t\t\t\tlabel: errorMessage,\n\t\t\t});\n\t\t} finally {\n\t\t\tloading = false;\n\t\t}\n\t}\n\n\tfunction handleCancel() {\n\t\tif (history.length > 0) {\n\t\t\thistory.back();","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/apps/desktop/src/components/onboarding/CloneForm.svelte#L72-L108","documentation":"Thrown by the onboarding clone flow after gitService.cloneRepo() succeeded but projectsService.addProject(targetDir) returned a falsy outcome. addProject returning null/undefined means the backend declined to register the freshly cloned directory as a GitButler project, so the clone is orphaned on disk.","triggerScenarios":"Any addProject call that comes back falsy: the cloned directory is not recognized as an adoptable repository (empty repo with no commits, odd worktree layout, nested .git), or the backend was not ready to accept project registration at that moment.","commonSituations":"Cloning a brand-new empty remote (no initial commit); target directory on a read-only or synced mount (Dropbox/OneDrive) confusing the scanner; joinPath produced an unexpected directory; racing app startup where the projects backend is still initializing.","solutions":["Verify the cloned directory on disk contains a valid .git and at least one commit; clone a non-empty ref if the repo was empty.","Retry adding the folder manually through the normal 'Add existing project' flow.","Check the backend logs for the specific reason addProject refused the path.","Ensure the target path is writable local storage, not a network/synced mount."],"exampleFix":"// before\nconst outcome = await projectsService.addProject(targetDir);\nif (!outcome) {\n  throw new Error(\"Failed to add project after cloning.\");\n}\n\n// after\nconst outcome = await projectsService.addProject(targetDir);\nif (!outcome) {\n  errors.push({\n    label: \"Cloned the repository but could not add it — add the folder manually from the project list\",\n  });\n  return;\n}","handlingStrategy":"try-catch","validationCode":"const targetDir = await backend.joinPath(targetDirPath, remoteUrl.name);\nconst hasGit = await backend.pathExists(`${targetDir}/.git`);\nif (!hasGit) {\n  errors.push({ label: \"Clone did not produce a git repository at \" + targetDir });\n  return;\n}\nconst outcome = await projectsService.addProject(targetDir);","typeGuard":null,"tryCatchPattern":"try {\n  const outcome = await projectsService.addProject(targetDir);\n  if (!outcome) throw new Error(\"Failed to add project after cloning.\");\n} catch (e) {\n  Sentry.captureException(e);\n  errors.push({ label: getErrorMessage(e) });\n}","preventionTips":["Clone into writable local storage, not network/synced mounts.","Confirm the remote has at least one commit before cloning during onboarding.","If addProject returns falsy, keep the cloned folder on disk and offer manual 'add existing project'."],"tags":["gitbutler","clone","onboarding","project-setup"],"backgroundTag":"repository-import-failed","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}