{"record":{"id":"04e0a9377c7f419b","repo":"different-ai/openwork","slug":"failed-to-copy-attachment-metadata-filename-i-04e0a9","errorCode":null,"errorMessage":"Failed to copy attachment \"${metadata.filename}\" into this worker workspace: expected ${file.size} bytes, wrote ${result.bytes}","messagePattern":"Failed to copy attachment \"(.+?)\" into this worker workspace: expected (.+?) bytes, wrote (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/app/src/react-app/domains/session/sync/attachment-file-part.ts","lineNumber":387,"sourceCode":"      filename: metadata.filename,\n      id,\n    });\n\n    let result: InboxUploadResult;\n    try {\n      result = await input.endpoint.client.uploadInbox(workspaceId, file, { path: inboxPath });\n    } catch (error) {\n      throw new Error(uploadErrorMessage(metadata.filename, error));\n    }\n\n    if (result.ok === false) {\n      throw new Error(`Failed to copy attachment \"${metadata.filename}\" into this worker workspace: upload was rejected`);\n    }\n    if (!result.path.trim()) {\n      throw new Error(`Failed to copy attachment \"${metadata.filename}\" into this worker workspace: upload did not return a path`);\n    }\n    if (result.bytes !== file.size) {\n      throw new Error(`Failed to copy attachment \"${metadata.filename}\" into this worker workspace: expected ${file.size} bytes, wrote ${result.bytes}`);\n    }\n\n    const workspacePath = workspaceInboxPath(result.path);\n    const absolutePath = joinWorkspaceRelativePath(workspaceRoot, workspacePath);\n    uploaded.push({\n      filename: metadata.filename,\n      mime: metadata.mime,\n      bytes: result.bytes,\n      workspacePath,\n      url: toFileUrl(absolutePath),\n      file,\n    });\n  }\n\n  return [\n    attachmentPathNotePart(uploaded),\n    ...(await Promise.all(uploaded.map(uploadedAttachmentFilePart))),\n  ];","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/app/src/react-app/domains/session/sync/attachment-file-part.ts#L369-L405","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// after uploadInbox resolves: if (result.bytes !== file.size) { console.error(`Upload truncated: expected ${file.size}, got ${result.bytes}`); } // then retry","handlingStrategy":"retry","validationCode":"const size = attachment.file.size; if (size !== attachment.sizeAtAttach) { showToast(`\"${attachment.filename}\" changed since attach — re-attach it`); return; }","typeGuard":null,"tryCatchPattern":"try { await composerAttachmentsToWorkspaceFileParts({ attachments, endpoint, sessionId, workspaceRoot }); } catch (e) { if (String(e.message).includes('bytes')) { await retryWithBackoff(() => sendWithAttachments()); } else { throw e; } }","preventionTips":["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."],"tags":["upload","attachments","integrity","byte-count"],"backgroundTag":"upload-byte-mismatch","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}