{"record":{"id":"66d6e44b08dff066","repo":"different-ai/openwork","slug":"uploaderrormessage-metadata-filename-error","errorCode":null,"errorMessage":"uploadErrorMessage(metadata.filename, error)","messagePattern":"uploadErrorMessage\\(metadata\\.filename, error\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/app/src/react-app/domains/session/sync/attachment-file-part.ts","lineNumber":377,"sourceCode":"    // chip already shows its uploading state. When the transport uploads the\n    // original file from its local path, re-encoding would detach that path,\n    // so the original bytes are sent instead.\n    const file = input.endpoint.client.uploadInboxPrefersOriginalFile?.(attachment.file)\n      ? attachment.file\n      : await compressImageFile(attachment.file);\n    const metadata = resolveAttachmentFileMetadata(file);\n    const id = input.createId ? input.createId() : randomAttachmentId();\n    const inboxPath = buildChatAttachmentInboxPath({\n      sessionId: input.sessionId,\n      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,","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/app/src/react-app/domains/session/sync/attachment-file-part.ts#L359-L395","documentation":"When uploading an attachment into the worker inbox via endpoint.client.uploadInbox, any thrown error is re-thrown as 'uploadErrorMessage(metadata.filename, error)' so the failure names the file and cause. This wraps network failures, permission errors, and client-side I/O errors from reading the file.","triggerScenarios":"uploadInbox throws — server unreachable, HTTP error on the upload request, file read failure (file moved/deleted/permission revoked after attach), or the inbox path could not be created.","commonSituations":"Temporary server outage while sending a message with attachments; the user moved/renamed/deleted the attached file on disk after adding it to the composer; sandbox permission prevents reading the file.","solutions":["Inspect the wrapped cause from uploadErrorMessage and retry the send if the failure was transient (network).","Re-attach the file if it was moved or deleted; verify it is readable.","Check server logs/inbox permissions if uploads persistently fail."],"exampleFix":"// before: await parts(store, draft) // throws with wrapped upload error | // after: try { await parts(store, draft) } catch (e) { showUploadError(e); } // names filename + cause","handlingStrategy":"try-catch","validationCode":"try { await attachment.file.slice(0, 1).arrayBuffer(); } catch { showToast(`Cannot read \"${attachment.filename}\" — re-attach the file`); return; }","typeGuard":null,"tryCatchPattern":"try { const parts = await composerAttachmentsToWorkspaceFileParts({ attachments, endpoint, sessionId, workspaceRoot }); } catch (e) { showToast(String(e.message)); if (isTransient(e)) { await retrySend(); } }","preventionTips":["Verify attached files still exist and are readable at send time.","Retry transient network failures with backoff before giving up.","Surface the wrapped filename+cause message instead of a generic failure."],"tags":["upload","attachments","network","io"],"backgroundTag":"attachment-upload-failed","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}