different-ai/openwork · error
size-mismatch
size-mismatch
Error message
Downloaded data changed while it was being saved.
What it means
While copying bytes from the staging file to the final destination, downloadBinaryToPath throws 'size-mismatch' if a read returns 0 bytes before `bytes` (the count just downloaded) have been copied. This means the staging file shrank or became unreadable between download and promotion — the downloaded data changed while it was being saved.
Source
Thrown at apps/desktop/electron/binary-transfer.mjs:333
// 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;
return { ...responseMetadata(response), path: destinationPath, bytes };
} catch (error) {
// Cleanup goes through the verified handle, never through the path, so a
// swapped parent cannot turn cleanup into an out-of-workspace deletion.
if (destinationFile) {
await destinationFile.truncate(0).catch(() => undefined);
await destinationFile.close().catch(() => undefined);
}
throw error;
} finally {
await stagingFile?.close().catch(() => undefined);View on GitHub (pinned to 2b7df46e8a)
Solutions
- Simply retry the whole download — this is detected corruption, and a fresh run to a fresh staging file is the fix.
- Ensure nothing purges the staging directory during downloads (antivirus exclusions, tmpwatch/systemd-tmpfiles settings).
- Check free disk space on the staging volume; ENOSPC can truncate files.
- Avoid sharing one staging/temp directory across concurrent downloads.
Example fix
// before
await downloadBinaryToPath({ url, destinationPath });
// after
import { transferErrorShape } from "./binary-transfer.mjs";
try {
await downloadBinaryToPath({ url, destinationPath });
} catch (e) {
if (e.code === "size-mismatch") await downloadBinaryToPath({ url, destinationPath }); // one clean retry
else throw e;
} Defensive patterns
Strategy: retry
Validate before calling
import { statfs } from "node:fs/promises";
const { bavail, bsize } = await statfs(path.dirname(destinationPath));
if (bavail * bsize < expectedBytes * 2) throw new Error("Insufficient free space for staging plus destination"); Try / catch
try {
await downloadBinaryToPath({ url, destinationPath });
} catch (e) {
if (e?.code === "size-mismatch") {
// staging file was truncated mid-copy: one clean retry on a fresh staging file
return downloadBinaryToPath({ url, destinationPath });
}
throw e;
} Prevention
- Exclude the staging/tmp directory from cleanup daemons and antivirus scanners.
- Keep ample free disk space on the staging volume.
- Don't share one staging directory across concurrent downloads.
- Retry the whole download once on size-mismatch — it indicates detected corruption.
When it happens
Trigger: During the staging-to-destination copy loop, stagingFile.read returns bytesRead === 0 while position < bytes, i.e. the staging file is shorter than the byte count recorded during streaming.
Common situations: Another process/user truncating or deleting the staging file mid-transfer (cleanup daemon, antivirus, temp-file sweeper); disk-full or fs errors surfacing as short reads; racing downloads sharing a temp directory.
Related errors
- destination-exists
- ${result}
- latest-mac.yml is missing sha512.
- The active OpenWork Cloud account changed while reconnecting
- Failed to copy attachment "${metadata.filename}" into this w
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/54d328738ea162f9.
Report an issue: GitHub.