{"record":{"id":"0bb97433d0459122","repo":"stablyai/orca","slug":"a-clone-is-already-in-progress-for-this-ssh-destin","errorCode":null,"errorMessage":"A clone is already in progress for this SSH destination","messagePattern":"A clone is already in progress for this SSH destination","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/main/ipc/repos.ts","lineNumber":521,"sourceCode":"  const clonePath = joinRemotePath(host, trimmedDestination, repoName)\n  if (relativePathInsideRoot(trimmedDestination, clonePath) === null) {\n    throw new Error('Clone path must be inside the destination directory')\n  }\n  const clonePathKey = normalizeRuntimePathForComparison(clonePath)\n  const existing = store.getRepos().find((repo) => {\n    return (\n      repo.connectionId === args.connectionId &&\n      normalizeRuntimePathForComparison(repo.path) === clonePathKey\n    )\n  })\n  if (existing && !isFolderRepo(existing)) {\n    emitRepoAdded('clone_url', true)\n    return existing\n  }\n\n  const remoteCloneKey = `${args.connectionId}:${clonePathKey}`\n  if (remoteCloneInFlightByPath.has(remoteCloneKey)) {\n    throw new Error('A clone is already in progress for this SSH destination')\n  }\n  const controller = new AbortController()\n  const metadata: ActiveRemoteCloneMetadata = {\n    connectionId: args.connectionId,\n    clonePath,\n    controller\n  }\n  activeRemoteClone = metadata\n  remoteCloneInFlightByPath.add(remoteCloneKey)\n  try {\n    // Why: match local clone by creating the parent first, or a fresh remote parent surfaces as spawn ENOENT.\n    await fsProvider.createDir(trimmedDestination)\n    // Why: the SSH relay runs git argv, not a shell; use the repo folder name so git creates it under the chosen parent.\n    await gitProvider.clone(\n      ['clone', '--progress', '--', args.url.trim(), repoName],\n      trimmedDestination,\n      {\n        signal: controller.signal,","sourceCodeStart":503,"sourceCodeEnd":539,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/repos.ts#L503-L539","documentation":"Thrown when remoteCloneInFlightByPath.has(remoteCloneKey), where remoteCloneKey = `${connectionId}:${clonePathKey}`. remoteCloneInFlightByPath is a module-level Set that tracks in-flight remote clones per (connection, normalized clone path). The set is populated when a clone starts and cleared in the finally block of the clone try/catch. The guard prevents two concurrent clones writing to the same destination.","triggerScenarios":"Two clone requests for the same connectionId and the same normalized clonePath while the first is still running. Common with double-click, retry storms, or two panes cloning the same repo to the same path.","commonSituations":"User clicks 'clone' twice rapidly; a workspace-restore clone races an explicit user clone; retry logic in the UI not deduping; orphaned entry from a clone whose finally didn't run (process crash mid-clone).","solutions":["Wait for the in-flight clone to finish (listen for repos:clone-progress completion) and reuse its result rather than issuing a second clone.","Dedupe at the caller: track active clone requests by (connectionId, path) and coalesce.","If the entry is stuck (clone crashed without running finally), it is cleared on the next clone's finally — but a main-process restart guarantees a clean set.","Show a UI hint that the destination is already being cloned and offer to focus that clone."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// remoteCloneInFlightByPath is module-private; mirror at the caller with a local Set keyed the same way.\nimport { normalizeRuntimePathForComparison } from '../../shared/cross-platform-path'\n\nconst inflight = new Set<string>()\nfunction cloneKey(connectionId: string, clonePath: string): string {\n  return `${connectionId}:${normalizeRuntimePathForComparison(clonePath)}`\n}\nfunction isCloneAlreadyInFlight(connectionId: string, clonePath: string): boolean {\n  return inflight.has(cloneKey(connectionId, clonePath))\n}","typeGuard":"function isCloneAlreadyInProgress(err: unknown): boolean {\n  return err instanceof Error && err.message === 'A clone is already in progress for this SSH destination'\n}","tryCatchPattern":"const key = cloneKey(connectionId, clonePath)\nif (inflight.has(key)) {\n  // reuse the in-flight clone's result instead of issuing a second one\n  return waitForCloneResult(key)\n}\ninflight.add(key)\ntry {\n  return await cloneRemoteRepo(store, mainWindow, { connectionId, url, destination })\n} finally {\n  inflight.delete(key)\n}","preventionTips":["Dedup clone requests at the caller keyed by (connectionId, normalized path) and coalesce concurrent ones onto a single result promise.","Disable the 'clone' button in the UI while a clone to that destination is in flight.","If the entry is stuck after a crash, restart the main process to clear the module-level Set."],"tags":["ssh","clone","concurrency","dedup","in-flight"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}