# How to Handle File Uploads and Downloads During Tool Execution in Composio

> Easily handle file uploads and downloads during tool execution with Composio. Our SDK automatically manages file transfers, streaming to S3 storage and downloading results locally.

- Repository: [Composio/composio](https://github.com/composiohq/composio)
- Tags: how-to-guide
- Published: 2026-02-19

---

**Composio’s SDK automatically manages file transfers during tool execution by detecting file paths in arguments, streaming them to secure S3 storage, and downloading results to a local temporary directory when `autoUploadDownloadFiles` is enabled.**

The Composio TypeScript SDK eliminates boilerplate for file operations by providing an integrated pipeline that handles uploads and downloads transparently during tool execution. When you invoke tools that declare file-related parameters in their schemas, the system intercepts file paths, manages cloud storage, and returns local URIs without manual intervention. This article examines the implementation details based on the ComposioHQ/composio source code, covering both automatic handling and manual overrides.

## Automatic File Handling Pipeline

The SDK implements a three-stage pipeline for file operations that activates when `autoUploadDownloadFiles` remains enabled (the default behavior).

### Stage 1: Detection

When initializing the `Composio` client, the SDK inspects tool schemas for properties marked with `file_uploadable: true`. According to the implementation in [`ts/packages/core/src/services/ToolExecutor.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/services/ToolExecutor.ts), the system scans incoming arguments for local file paths or remote URLs before executing the tool.

### Stage 2: Upload

Detected files are read from disk or fetched from URLs, MIME-type detected, and streamed to Composio’s secure S3 infrastructure. The SDK replaces the original argument value with a structured metadata object containing `name`, `mimetype`, and `s3key`. This transformation occurs transparently before the tool receives the payload.

### Stage 3: Download

If a tool’s response contains an `s3url` field with a corresponding `mimetype`, the SDK automatically fetches the object to `~/.composio/files/` and enriches the result with additional fields: `uri` (local temporary path), `file_downloaded: true`, and the original `s3url`.

```typescript
import { Composio } from '@composio/core';

const composio = new Composio({ apiKey: process.env.COMPOSIO_API_KEY });

const result = await composio.tools.execute('document-processor', {
  arguments: {
    // Local path or HTTPS URL automatically uploaded
    file: '/path/to/report.pdf'
  }
});

// Access the downloaded file path
console.log(result.data.file?.uri); // e.g., ~/.composio/files/report-abc123.pdf

```

## Configuring Automatic File Handling

The `autoUploadDownloadFiles` flag in the `Composio` constructor controls this behavior. Located in [`ts/packages/core/src/composio.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/composio.ts), this boolean option defaults to `true`, enabling the automatic pipeline for all tool executions.

To disable automatic handling and implement custom file logic:

```typescript
import { Composio } from '@composio/core';

const composio = new Composio({
  apiKey: process.env.COMPOSIO_API_KEY,
  autoUploadDownloadFiles: false  // Disable automatic upload/download
});

```

When disabled, the SDK passes file arguments verbatim to tools without S3 interception, requiring manual management via the `Files` model.

## Manual File Operations

For scenarios requiring explicit control, the `Files` class in [`ts/packages/core/src/models/Files.node.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/models/Files.node.ts) exposes low-level `upload()` and `download()` methods.

### Manual Upload

When automatic handling is disabled, use `composio.files.upload()` to stream files to S3 and receive the metadata object required by tool schemas:

```typescript
const uploaded = await composio.files.upload({
  filePath: '/path/to/image.png',    // Supports local paths or HTTP URLs
  toolSlug: 'document-processor',
  toolkitSlug: 'image-tools'
});

// Pass structured metadata to tool
const result = await composio.tools.execute('document-processor', {
  arguments: {
    file: uploaded  // { name, mimetype, s3key }
  }
});

```

### Manual Download

Extract files from tool responses manually by invoking `composio.files.download()` with the S3 URL returned by the tool:

```typescript
const result = await composio.tools.execute('document-processor', { 
  arguments: { documentId: 'doc-123' } 
});

if (result.data.output?.s3url) {
  const downloaded = await composio.files.download({
    s3Url: result.data.output.s3url,
    toolSlug: 'document-processor',
    mimeType: result.data.output.mimetype ?? 'application/octet-stream'
  });

  console.log('File saved to:', downloaded.filePath);
}

```

## Error Handling

The SDK throws `ComposioFileUploadError` for file operation failures, providing actionable context through the `possibleFixes` property. Import this error class from `@composio/core` to implement granular error handling:

```typescript
import { ComposioFileUploadError } from '@composio/core';

try {
  await composio.tools.execute('document-processor', {
    arguments: { file: '/nonexistent/file.txt' }
  });
} catch (err) {
  if (err instanceof ComposioFileUploadError) {
    console.error('Upload failed:', err.message);
    console.log('Suggested fixes:', err.possibleFixes);
  }
  throw err;
}

```

## Summary

- **Automatic handling** is enabled by default via `autoUploadDownloadFiles: true` in the `Composio` constructor, scanning for `file_uploadable` schema properties.
- The SDK streams files to S3 during upload and retrieves them to `~/.composio/files/` during download, transforming arguments between local paths and `{ name, mimetype, s3key }` metadata.
- **Manual control** is available through `composio.files.upload()` and `composio.files.download()` in [`ts/packages/core/src/models/Files.node.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/models/Files.node.ts) when automatic handling is disabled.
- Handle failures specifically using `ComposioFileUploadError` to access diagnostic suggestions.

## Frequently Asked Questions

### How do I check if automatic file handling is working during tool execution?

Verify that the tool schema includes `file_uploadable: true` on the relevant property and ensure `autoUploadDownloadFiles` is not set to `false` in your `Composio` constructor. The SDK modifies arguments containing valid file paths into S3 metadata objects before transmission, and enriches responses containing `s3url` fields with local `uri` paths.

### Can I use remote URLs instead of local file paths for uploads?

Yes. The `upload()` method in [`ts/packages/core/src/models/Files.node.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/models/Files.node.ts) accepts both local filesystem paths and HTTP/HTTPS URLs in the `filePath` parameter. The SDK fetches remote content and streams it to S3 storage automatically.

### Where does Composio store downloaded files on my local machine?

Downloaded files are written to the `~/.composio/files/` directory by default. The SDK generates unique filenames to prevent collisions and returns the absolute path in the `uri` field of the response object.

### What happens if a tool returns an S3 URL but automatic downloads are disabled?

When `autoUploadDownloadFiles` is `false`, the raw response containing `s3url` and `mimetype` passes through unchanged. You must explicitly call `composio.files.download()` with the S3 URL to retrieve the file to local storage.