different-ai/openwork · error

destination-exists

destination-exists

Error message

Download destination already exists.

What it means

downloadBinaryToPath creates the destination exclusively with open(path, "wx"), which never follows a final symlink; an EEXIST is converted to the coded error 'destination-exists'. This prevents silently overwriting user files and blocks symlink attacks on the destination path. The destination must also resolve inside the authorized roots before this check.

Source

Thrown at apps/desktop/electron/binary-transfer.mjs:322

        bytes += value.byteLength;
        if (bytes > maxBytes) {
          await reader.cancel();
          throw transferError(`Download exceeds the ${maxBytes}-byte limit.`, "file-too-large");
        }
        await writeAll(stagingFile, value);
      }
    }
    if (bytes === 0) throw transferError("Download response was empty.", "zero-byte-file");
    // Only a complete download reaches the workspace. Revalidate the
    // destination, create it exclusively ("wx" never follows a final
    // symlink), and prove by device and inode that the created file resides
    // inside the authorized root before a single byte is written to it.
    await resolveAuthorizedPath(input?.destinationPath, options?.authorizedRoots);
    try {
      destinationFile = await open(destinationPath, "wx");
    } catch (error) {
      if (error?.code === "EEXIST") {
        throw transferError("Download destination already exists.", "destination-exists");
      }
      throw error;
    }
    await verifyOpenFileWithinRoot(destinationFile, destinationPath, destination.rootRealPath, "Download destination");
    const buffer = Buffer.allocUnsafe(1024 * 1024);
    let position = 0;
    while (position < bytes) {
      signal?.throwIfAborted();
      const { bytesRead } = await stagingFile.read(buffer, 0, Math.min(buffer.length, bytes - position), position);
      if (bytesRead === 0) {
        throw transferError("Downloaded data changed while it was being saved.", "size-mismatch");
      }
      await writeAll(destinationFile, buffer.subarray(0, bytesRead));
      position += bytesRead;
    }
    await destinationFile.sync();
    await destinationFile.close();
    destinationFile = undefined;

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Delete or rename the existing file first (fs.rm / rename) if overwriting is intended.
  2. Pick a unique destinationPath (timestamp/UUID suffix or version in the filename).
  3. Add an existence check before the call and branch: skip, resume, or overwrite explicitly.
  4. Serialize concurrent workers so only one downloads to a given path.

Example fix

// before
await downloadBinaryToPath({ url, destinationPath });
// after
import { rm } from "node:fs/promises";
await rm(destinationPath, { force: true }); // explicit overwrite intent
await downloadBinaryToPath({ url, destinationPath });
Defensive patterns

Strategy: validation

Validate before calling

import { lstat } from "node:fs/promises";
let exists = false;
try { await lstat(destinationPath); exists = true; } catch (e) { if (e.code !== "ENOENT") throw e; }
if (exists) throw new Error(`Choose another destination; ${destinationPath} already exists`);

Type guard

async function isFreeDestination(p) {
  try { await lstat(p); return false; } catch (e) { return e.code === "ENOENT"; }
}

Try / catch

try {
  await downloadBinaryToPath({ url, destinationPath });
} catch (e) {
  if (e?.code === "destination-exists") {
    return { ok: false, reason: "exists", path: destinationPath };
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling downloadBinaryToPath with destinationPath pointing at a path that already exists (file, or dangling/symlinked entry) — open("wx") raises EEXIST which is remapped to this error.

Common situations: Re-running a setup script that already downloaded the file; two concurrent workers downloading to the same path; stale artifact from a previous version; a symlink planted at the destination path.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/7ada1f1eeedb40e5. Report an issue: GitHub.