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
- Retry the whole upload flow so a fresh pre-signed URL is minted.
- Ensure the mimeType passed to the SDK matches the actual content type used when the URL was requested.
- 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
- Upload promptly after requesting the presigned URL.
- Keep Content-Type consistent between URL request and PUT.
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
- Failed to download file: ${response.statusText}
- Error downloading file: {_sanitize_url_for_logging(self.s3ur
- Failed to fetch file from URL: {e.cause}
- Failed to upload file to S3: ${uploadResponse.statusText}
- Failed to parse tool router session files mount upload optio
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/2530e07cdf478d87.
Report an issue: GitHub.