ComposioHQ/composio · error · Error

Failed to upload file to S3: ${uploadResponse.statusText}

Error message

Failed to upload file to S3: ${uploadResponse.statusText}

What it means

Thrown by uploadFileToS3 when the PUT/POST to the pre-signed S3 upload URL returned by Composio returns a non-OK status. The upload URL is obtained from the backend; only statusText is reported.

Source

Thrown at ts/packages/core/src/utils/fileUtils.node.ts:262

  // Note: do not set `Content-Length` manually. Node.js's built-in fetch (undici)
  // computes it from `body` and rejects any user-supplied value with
  // `InvalidArgumentError: invalid content-length header`, which surfaces as
  // `TypeError: fetch failed` and breaks every `file_uploadable` connector tool
  // on Node 22+.
  // SSRF guard: `new_presigned_url` comes from the API response, which the SDK
  // treats as untrusted — a response naming an internal address would otherwise
  // have the file's bytes PUT to it. See ssrfGuard.node.ts.
  const uploadResponse = await ssrfSafeFetch(signedURL, {
    method: 'PUT',
    body: uploadBuffer,
    signal,
    headers: {
      'Content-Type': mimeType,
    },
  });

  if (!uploadResponse.ok) {
    throw new Error(`Failed to upload file to S3: ${uploadResponse.statusText}`);
  }

  return key;
};

const readFile = async (
  file: File | string,
  signal?: AbortSignal
): Promise<{ fileName: string; content: string; mimeType: string }> => {
  if (file instanceof File) {
    const content = await file.arrayBuffer();
    return {
      fileName: file.name,
      content: uint8ArrayToBase64(new Uint8Array(content)),
      mimeType: file.type,
    };
  } else if (typeof file === 'string') {
    if (isHttpUrl(file)) {

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Retry the whole upload flow so a fresh pre-signed URL is minted.
  2. Ensure the mimeType passed to the SDK matches the actual content type used when the URL was requested.
  3. Check for corporate proxies/VPVs interfering with PUT requests to S3.
Defensive patterns

Strategy: retry

Try / catch

try { await upload(...); } catch (e) {
  if ((e as Error).message.startsWith('Failed to upload file to S3')) { /* retry whole flow for fresh presigned URL */ }
}

Prevention

When it happens

Trigger: Uploading a file where the pre-signed URL has expired (403), the Content-Type differs from what was signed, the body size exceeds the signed limit, or S3 returns 5xx.

Common situations: Long delays between getting the upload URL and performing the upload, mismatched MIME type, network proxies stripping headers, transient S3 errors.

Related errors


AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28). Data as JSON: /api/errors/2530e07cdf478d87. Report an issue: GitHub.