different-ai/openwork · error
Failed to copy attachment "${metadata.filename}" into this w
Error message
Failed to copy attachment "${metadata.filename}" into this worker workspace: expected ${file.size} bytes, wrote ${result.bytes} What it means
After a successful upload the client verifies the server wrote exactly file.size bytes. A mismatch means a partial or corrupted write, so it throws this error with the expected vs actual byte counts. This protects tools from operating on truncated attachment copies.
Source
Thrown at apps/app/src/react-app/domains/session/sync/attachment-file-part.ts:387
filename: metadata.filename,
id,
});
let result: InboxUploadResult;
try {
result = await input.endpoint.client.uploadInbox(workspaceId, file, { path: inboxPath });
} catch (error) {
throw new Error(uploadErrorMessage(metadata.filename, error));
}
if (result.ok === false) {
throw new Error(`Failed to copy attachment "${metadata.filename}" into this worker workspace: upload was rejected`);
}
if (!result.path.trim()) {
throw new Error(`Failed to copy attachment "${metadata.filename}" into this worker workspace: upload did not return a path`);
}
if (result.bytes !== file.size) {
throw new Error(`Failed to copy attachment "${metadata.filename}" into this worker workspace: expected ${file.size} bytes, wrote ${result.bytes}`);
}
const workspacePath = workspaceInboxPath(result.path);
const absolutePath = joinWorkspaceRelativePath(workspaceRoot, workspacePath);
uploaded.push({
filename: metadata.filename,
mime: metadata.mime,
bytes: result.bytes,
workspacePath,
url: toFileUrl(absolutePath),
file,
});
}
return [
attachmentPathNotePart(uploaded),
...(await Promise.all(uploaded.map(uploadedAttachmentFilePart))),
];View on GitHub (pinned to 2b7df46e8a)
Solutions
- Retry the upload to get a clean full write.
- Compare the source file on disk with the stored copy; re-attach if the file changed since attach time.
- Investigate the server storage layer for truncation of large files or transformations.
Example fix
// after uploadInbox resolves: if (result.bytes !== file.size) { console.error(`Upload truncated: expected ${file.size}, got ${result.bytes}`); } // then retry Defensive patterns
Strategy: retry
Validate before calling
const size = attachment.file.size; if (size !== attachment.sizeAtAttach) { showToast(`"${attachment.filename}" changed since attach — re-attach it`); return; } Try / catch
try { await composerAttachmentsToWorkspaceFileParts({ attachments, endpoint, sessionId, workspaceRoot }); } catch (e) { if (String(e.message).includes('bytes')) { await retryWithBackoff(() => sendWithAttachments()); } else { throw e; } } Prevention
- Re-upload automatically on byte-count mismatch; treat as a partial write.
- Re-read file metadata at send time to catch files modified after attach.
- Investigate server storage for truncation or transformation of uploads.
When it happens
Trigger: uploadInbox returns result.bytes !== file.size — interrupted transfer still reported success, server-side truncation, encoding/transformation of the file during storage, or a stale size from a re-encoded image.
Common situations: Flaky network with a lossy upload pipeline; server storage layer truncating large files; the file changed on disk between read and upload so sizes disagree.
Related errors
- uploadErrorMessage(metadata.filename, error)
- Failed to copy attachment "${metadata.filename}" into this w
- Failed to copy attachment "${metadata.filename}" into this w
- latest-mac.yml is missing sha512.
- Workspace path is unavailable; attachments could not be copi
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/04e0a9377c7f419b.
Report an issue: GitHub.