stablyai/orca · error · Error

Clone failed: ${message}

Error message

Clone failed: ${message}

What it means

Thrown when the underlying git clone subprocess fails during repos:clone. The handler cleans up the claimed clone target, extracts the error message from the thrown value (Error.message or String(err)), and re-throws prefixed with 'Clone failed: '. The clone is run with --progress and a nonInteractiveGitEnv() to avoid Git Credential Manager OAuth popups.

Source

Thrown at src/main/ipc/repos.ts:2406

        const pendingController = new AbortController()
        pendingLocalCloneControllers.add(pendingController)
        try {
          // Why: use the parent destination as cwd so the runner detects a WSL path and routes through wsl.exe.
          // Why: '--' isolates the URL so a malicious URL can't be read as git flags (command injection).
          proc = await gitSpawnAfterWindowsEnvironmentReady(
            ['clone', '--progress', '--', args.url, clonePath],
            {
              cwd: args.destination,
              // Why: without this, an auth-needing clone pops Git Credential Manager's OAuth window on Windows, unclosable in a restricted env (issue #7652).
              env: nonInteractiveGitEnv(),
              signal: pendingController.signal,
              stdio: ['ignore', 'ignore', 'pipe']
            }
          )
        } catch (err) {
          await cleanupClaimedCloneTarget(clonePath, claimedTarget)
          const message = err instanceof Error ? err.message : String(err)
          throw new Error(`Clone failed: ${message}`)
        } finally {
          pendingLocalCloneControllers.delete(pendingController)
        }
        await new Promise<void>((resolve, reject) => {
          const generation = nextCloneGeneration++
          latestCloneGenerationByPath.set(clonePathKey, generation)
          const metadata: ActiveCloneMetadata = {
            path: clonePath,
            pathKey: clonePathKey,
            claimedTarget,
            process: proc,
            abortRequested: false,
            generation,
            pendingAbortCleanup: null,
            resolvePendingAbortCleanup: null
          }
          cloneMetadataRef.current = metadata
          activeClone = metadata

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Inspect the captured message after the 'Clone failed: ' prefix — it usually names the real cause (auth, DNS, disk).
  2. For auth issues, configure credentials (SSH agent, credential helper, or PAT) and retry.
  3. Ensure the destination directory is empty and writable before cloning.
  4. If the user cancelled, treat AbortError as non-fatal and skip retry.
  5. On remote hosts, verify the git binary version meets the baseline.

Example fix

// before
try {
  await ipc.invoke('repos:clone', args)
} catch (e) {
  notify(e.message)
}

// after
try {
  await ipc.invoke('repos:clone', args)
} catch (e) {
  const cause = e.message.replace(/^Clone failed:\s*/, '')
  if (/abort/i.test(cause)) return // user-cancelled
  if (/auth|403|401|permission/i.test(cause)) promptForCredentials(args.url)
  else notify(`Clone failed: ${cause}`)
}
Defensive patterns

Strategy: try-catch

Validate before calling

import { stat } from 'fs/promises'
import { access } from 'fs/promises'

async function preflightClone(url: string, destination: string): Promise<string | null> {
  try { await access(destination); return 'Destination already exists.' } catch { /* ok */ }
  try {
    const s = await stat(destination)
    if (!s.isDirectory()) return 'Destination is not a directory.'
  } catch { /* will be created */ }
  if (!/^https?:|^git@|^[A-Za-z]+@/.test(url)) return 'Unsupported clone URL scheme.'
  return null
}

const issue = await preflightClone(args.url, args.destination)
if (issue) { showError(issue); return }
await ipc.invoke('repos:clone', args)

Type guard

function isAbortFailure(message: string): boolean {
  return /abort|cancel/i.test(message)
}

Try / catch

try {
  await ipc.invoke('repos:clone', args)
} catch (e) {
  const cause = (e as Error).message.replace(/^Clone failed:\s*/, '')
  if (/abort|cancel/i.test(cause)) return // user-cancelled
  if (/auth|401|403|permission denied/i.test(cause)) promptForCredentials(args.url)
  else showCloneError(cause)
}

Prevention

When it happens

Trigger: Network or auth failure reaching the remote (HTTP 401/403, SSH key rejected), an invalid or unreachable URL, a destination that cannot be written, the abort signal firing (user cancelled), or git not installed / wrong git on PATH.

Common situations: Private repo cloned without credentials configured; corporate proxy or firewall blocking the remote; destination path already exists and is non-empty; WSL/SSH host git version too old; user clicked cancel mid-clone.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/61093849c4a187f3. Report an issue: GitHub.