# How File Uploads Work with the setInputFiles Method in ego-browser

> Learn how file uploads work in ego-browser using the setInputFiles method. Upload files programmatically with Chrome DevTools Protocol integration.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: how-to-guide
- Published: 2026-07-26

---

**The `setInputFiles` helper in ego-browser enables agent scripts to programmatically upload files to file input elements by delegating to the Chrome DevTools Protocol's `DOM.setFileInputFiles` command.**

The `citrolabs/ego-lite` repository provides a browser automation framework where the `setInputFiles` method serves as the primary mechanism for simulating file uploads within agent scripts. This helper abstracts the complexity of Chrome DevTools Protocol (CDP) interactions, allowing developers to set absolute file paths on `<input type="file">` elements using flexible selectors. Understanding the internal pipeline from the public API to the underlying CDP call is essential for implementing reliable file upload automation.

## Understanding the setInputFiles API Architecture

The `setInputFiles` method is exposed through a layered architecture that separates the public helper interface from the low-level driver implementation.

### Public API Entry Point in helpers.ts

The helper is officially exported from [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) at line 99, making it available to agent execution contexts:

```typescript
// src/helpers.ts (line 99)
export { setInputFiles } from "./driver/files.js";

```

This re-export pattern ensures that when an agent script receives its helper context, `setInputFiles` is readily accessible alongside other automation primitives.

### Core Driver Implementation in files.ts

The actual upload logic resides in [`src/driver/files.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/files.ts), where the function accepts a selector and file path(s):

```typescript
// src/driver/files.ts
export async function setInputFiles(selector, path) {
  const files = Array.isArray(path) ? path : [path];
  await withHandle(selector, async ({ objectId, sessionId }) => {
    await cdp("DOM.setFileInputFiles", { files, objectId }, sessionId);
  });
}

```

The method signature supports both single files (string) and multiple files (array), normalizing the input into an array before processing.

## The Implementation Pipeline

File uploads traverse three distinct stages: selector resolution, CDP session management, and native browser execution.

### Selector Resolution with withHandle

The `withHandle` utility imported from [`src/driver/element-ops.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/element-ops.ts) resolves flexible selector strings into CDP object references:

- **CSS selectors**: Standard DOM queries (`input#resume`)
- **Reference syntax**: `@ref` notation for cached element handles (`@123`)
- **Locator syntax**: `loc=css:` or `xpath=` prefixes for explicit strategy selection

`withHandle` returns an `objectId` representing the CDP remote object and a `sessionId` ensuring the command executes in the correct browser context.

### CDP Command Execution

The `cdp` function (from [`src/cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/cdp-eval.ts)) transmits the `DOM.setFileInputFiles` command to the Chrome DevTools Protocol:

```typescript
await cdp("DOM.setFileInputFiles", { files, objectId }, sessionId);

```

This CDP method accepts:
- **files**: Array of absolute file system paths
- **objectId**: The remote object ID of the target `<input type="file">` element

Upon execution, the browser updates the element's `files` property to reflect the specified local files, triggering standard input change events as if a user had manually selected them through the file picker dialog.

## Practical Code Examples

The `setInputFiles` method supports various selector patterns and file configurations.

### Single File Upload

Upload a resume to a specific input element:

```javascript
await setInputFiles('input#resume', '/home/user/documents/resume.pdf');

```

### Multiple File Upload

Batch upload images to a gallery input by passing an array of paths:

```javascript
await setInputFiles('#gallery-upload', [
  '/tmp/img1.png',
  '/tmp/img2.png',
]);

```

### Alternative Selector Patterns

Use reference handles or explicit locator strategies when working with cached elements or complex DOM queries:

```javascript
// Using @ref handle from previous element capture
await setInputFiles('@123', '/var/data/report.csv');

// Using loc= prefix for CSS selector
await setInputFiles('loc=css:#profile-pic', '/pics/avatar.png');

```

## Error Handling and Edge Cases

Any errors originating from the CDP layer—such as invalid file paths, permission denials, or selector resolution failures—propagate through the helper framework as standard JavaScript exceptions. Agent scripts can implement standard `try...catch` blocks to handle these scenarios:

```javascript
try {
  await setInputFiles('#upload', '/nonexistent/file.pdf');
} catch (error) {
  console.error('Upload failed:', error.message);
}

```

The promise returned by `setInputFiles` resolves only after the browser confirms the file list update, ensuring synchronous-style code flow in async/await patterns.

## Summary

- **`setInputFiles`** is exported from [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) (line 99) and implemented in [`src/driver/files.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/files.ts) for the `citrolabs/ego-lite` repository.
- The method accepts flexible selectors (CSS, `@ref`, `loc=`, `xpath=`) and absolute file paths as strings or arrays.
- **CDP integration**: Uses `DOM.setFileInputFiles` via `withHandle` from [`src/driver/element-ops.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/element-ops.ts) to resolve elements and update file inputs.
- **Synchronous feel**: Returns a promise that resolves when the browser confirms the upload, with errors bubbling up as standard JavaScript exceptions.

## Frequently Asked Questions

### What selector types does setInputFiles support?

The method supports CSS selectors (`#id`, `.class`), reference handles (`@123`), and explicit locator strategies (`loc=css:`, `loc=xpath:`). The `withHandle` utility in [`src/driver/element-ops.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/element-ops.ts) normalizes these formats into CDP object IDs before execution.

### How does setInputFiles handle multiple file uploads?

Pass an array of absolute file paths as the second argument. The function automatically detects arrays versus single strings, normalizing single paths into `['path/to/file']` before passing the `files` array to the `DOM.setFileInputFiles` CDP command.

### What happens if the file path is invalid?

The Chrome DevTools Protocol will reject invalid paths, and the resulting error propagates through the `cdp` wrapper in [`src/cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/cdp-eval.ts) as a standard JavaScript exception. The promise rejects immediately, allowing agent scripts to catch and handle file system errors programmatically.

### Is there a file size limit when using setInputFiles?

`setInputFiles` itself imposes no size restrictions; limits depend on the underlying browser's CDP implementation and the target website's file upload constraints. The method merely sets the file references on the input element—it does not validate file contents or sizes before delegation to the browser.