stablyai/orca · warning · Error

Destination folder already exists

Error message

Destination folder already exists

What it means

Thrown by assertDownloadFolderDestinationAvailable() after the user picks a destination parent folder in the OS dialog. The handler joins destinationParent with the sanitized remote basename and stat()s the resulting path; if stat succeeds the name is already taken, so the download is aborted before any transfer. ENOENT is the only acceptable result (path is free); any other stat error is re-thrown. This is a deliberate pre-flight collision check so the later rename-based promotion does not clobber existing data.

Source

Thrown at src/main/ipc/filesystem-download-folder.ts:35

  return value
}

function createSiblingTransferPath(destinationPath: string, suffix: string): string {
  // Why: promotion uses rename/no-clobber operations that must stay on the
  // destination volume, so transfer paths intentionally remain siblings.
  return join(dirname(destinationPath), `.${randomUUID()}.${suffix}`)
}

async function assertDownloadFolderDestinationAvailable(destinationPath: string): Promise<void> {
  try {
    await stat(destinationPath)
  } catch (error) {
    if (isENOENT(error)) {
      return
    }
    throw error
  }
  throw new Error('Destination folder already exists')
}

async function cleanupLocalTransferDirectory(dirPath: string): Promise<void> {
  try {
    await rm(dirPath, { recursive: true, force: true })
  } catch (error) {
    // Why: cleanup must not mask the transfer error, but a leaked recursive
    // download tree needs enough visibility to diagnose and remove it.
    console.warn(`[filesystem] Failed to remove temporary folder download '${dirPath}'`, error)
  }
}

// Why: keep folder-download IPC out of filesystem.ts — that module is already large.
export function registerFilesystemDownloadFolderHandlers(): void {
  ipcMain.handle(
    'fs:downloadFolder',
    async (
      event,

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Choose a different destination parent folder in the dialog.
  2. Rename or move the existing same-named entry out of the chosen parent before retrying.
  3. If the existing entry is a stale partial download, delete it and retry.
  4. Sanitize/seed a different destination basename upstream if collisions are routine.

Example fix

// before: destination = ~/Downloads/myproj (already exists)
// after: pick an empty parent, or rename existing first
await fs.rename(`${destParent}/${basename}`, `${destParent}/${basename}.old`)
// then retry fs:downloadFolder
Defensive patterns

Strategy: validation

Validate before calling

// After the user picks a destination parent, pre-check the joined path is free
import { stat } from 'node:fs/promises'
import { join } from 'node:path'
async function isDestFree(parent: string, basename: string): Promise<boolean> {
  try { await stat(join(parent, basename)); return false } catch { return true }
}

Try / catch

// Treat the IPC error as a recoverable name collision
try {
  await window.api.fs.downloadFolder({ dirPath, connectionId })
} catch (e) {
  if (e instanceof Error && /already exists/.test(e.message)) {
    // prompt user to pick another parent or rename, then retry
  } else throw e
}

Prevention

When it happens

Trigger: fs:downloadFolder is invoked, the user selects e.g. ~/Downloads, and a folder or file named like the remote directory (after sanitizeLocalDownloadFileName) already exists directly under that chosen parent. Also reachable if a previous download of the same remote folder left a same-named directory behind.

Common situations: Repeated downloads of the same remote folder into the same parent; a file and folder name clash; a sanitized basename that collided after illegal characters were stripped; a leftover partial download from a crashed prior run that was not cleaned up.

Related errors


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