different-ai/openwork · error

uploadErrorMessage(metadata.filename, error)

Error message

uploadErrorMessage(metadata.filename, error)

What it means

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.

Source

Thrown at apps/app/src/react-app/domains/session/sync/attachment-file-part.ts:377

    // chip already shows its uploading state. When the transport uploads the
    // original file from its local path, re-encoding would detach that path,
    // so the original bytes are sent instead.
    const file = input.endpoint.client.uploadInboxPrefersOriginalFile?.(attachment.file)
      ? attachment.file
      : await compressImageFile(attachment.file);
    const metadata = resolveAttachmentFileMetadata(file);
    const id = input.createId ? input.createId() : randomAttachmentId();
    const inboxPath = buildChatAttachmentInboxPath({
      sessionId: input.sessionId,
      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,

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Inspect the wrapped cause from uploadErrorMessage and retry the send if the failure was transient (network).
  2. Re-attach the file if it was moved or deleted; verify it is readable.
  3. Check server logs/inbox permissions if uploads persistently fail.

Example fix

// before: await parts(store, draft) // throws with wrapped upload error | // after: try { await parts(store, draft) } catch (e) { showUploadError(e); } // names filename + cause
Defensive patterns

Strategy: try-catch

Validate before calling

try { await attachment.file.slice(0, 1).arrayBuffer(); } catch { showToast(`Cannot read "${attachment.filename}" — re-attach the file`); return; }

Try / catch

try { const parts = await composerAttachmentsToWorkspaceFileParts({ attachments, endpoint, sessionId, workspaceRoot }); } catch (e) { showToast(String(e.message)); if (isTransient(e)) { await retrySend(); } }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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