# How to Handle File Uploads with setInputFiles in ego-lite

> Learn how to handle file uploads with ego-lite's setInputFiles. This helper efficiently uploads local files to input elements using CDP commands for seamless browser interaction.

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

---

**The `setInputFiles` helper uploads local files to `<input type="file">` elements by resolving selectors to DOM handles and dispatching `DOM.setFileInputFiles` CDP commands to the browser.**

The `ego-lite` framework provides this high-level utility in [`src/driver/files.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/files.ts) to automate file uploads within agent scripts. Exposed through [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) and [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts), the function bridges agent logic with Chrome DevTools Protocol (CDP) to attach host filesystem files directly to web forms.

## Architecture of setInputFiles

The implementation relies on a coordinated stack spanning selector resolution, CDP messaging, and public API exposure.

**[`src/driver/files.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/files.ts)** contains the core `setInputFiles` function. It accepts a selector string and one or more absolute file paths, then orchestrates the upload sequence.

**[`src/driver/element-ops.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/element-ops.ts)** provides the `withHandle` utility used by `setInputFiles`. This resolves selectors—whether CSS, XPath, `loc=`, or `@ref` formats—to CDP object handles (`objectId`) and session IDs required for DOM interaction.

**[`src/cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/cdp-eval.ts)** wraps the low-level CDP transport via `ego.sendCDPMessage`. The `cdp` function forwards the `DOM.setFileInputFiles` command to the browser runtime.

**[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)** re-exports `setInputFiles` into the public helper context injected into every agent script scope, while **[`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts)** surfaces the function at the top-level export table for CLI and SDK consumers.

## How setInputFiles Works

When invoked, the function executes a four-step flow:

1. **Selector resolution** – `withHandle` converts the provided selector to a DOM node handle using the current task-space session, supporting automatic re-attachment if the session was lost.

2. **Path normalization** – The helper accepts a string or array of strings; each entry must be an absolute path accessible from the process running the ego-lite binary.

3. **CDP command dispatch** – The function calls `cdp("DOM.setFileInputFiles", ...)` with the resolved object ID and normalized file paths, instructing the browser to populate the input element.

4. **Promise resolution** – The returned Promise settles once the browser confirms attachment. Errors such as missing elements or invalid input types throw immediately.

Errors throw `ElementResolutionError` with a `permanent` kind, indicating the failure stems from incorrect usage (e.g., selector not found, non-file input, or missing local file) rather than transient network issues, thus preventing automatic retries.

## setInputFiles Code Examples

Upload a single file using a CSS selector:

```javascript
await setInputFiles('#profile-pic', '/home/user/pictures/avatar.png');

```

Upload multiple files by passing an array of absolute paths:

```javascript
await setInputFiles('#gallery-upload', [
  '/home/user/photos/img1.jpg',
  '/home/user/photos/img2.jpg',
]);

```

Use XPath or `loc=` locator strategies:

```javascript
// XPath selector
await setInputFiles('xpath=//input[@id="resume"]', '/tmp/resume.pdf');

// Site-skill generated locator
await setInputFiles('loc=css:#document-upload', '/var/docs/report.docx');

```

## Error Handling and Constraints

**Absolute paths required**: The implementation in [`src/driver/files.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/files.ts) strictly requires absolute file paths. Relative paths or paths inaccessible to the ego-lite runtime process will cause the operation to fail with a file-not-found error propagated from the CDP layer.

**Element type validation**: The target element must be an `<input type="file">`. Calling `setInputFiles` on other element types results in an `ElementResolutionError` with the `permanent` flag set, halting the agent task immediately.

**Session management**: The function automatically respects the current task-space session and handles re-attachment if the browser connection drops during the upload process.

## Summary

- **`setInputFiles`** in [`src/driver/files.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/files.ts) provides the primary API for automated file uploads in ego-lite.
- The function requires **absolute file paths** and supports both single files and arrays for multiple uploads.
- **CDP command** `DOM.setFileInputFiles` performs the actual attachment after selector resolution via `withHandle`.
- **Errors** throw `ElementResolutionError` with permanent status, preventing retries on invalid selectors or missing files.
- Available globally in agent scripts through **[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)** and the CLI/SDK via **[`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts)**.

## Frequently Asked Questions

### Can setInputFiles use relative file paths?

No. The implementation strictly requires absolute paths accessible from the host running the ego-lite binary. Relative paths are not resolved automatically and will trigger an error when the CDP command executes.

### How do I upload multiple files simultaneously?

Pass an array of absolute paths as the second argument. `setInputFiles` detects arrays and dispatches a single `DOM.setFileInputFiles` command containing all paths, populating the file input's `files` property with multiple entries.

### What happens if the selector doesn't match a file input element?

The function throws an `ElementResolutionError` with a `permanent` kind. This error type prevents the task runner from retrying the action, as it indicates a structural mismatch (wrong selector or element type) rather than a recoverable failure.

### Is setInputFiles available without importing it in agent scripts?

Yes. [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) re-exports `setInputFiles` into the global helper context injected into every agent script, making it available as a global function. It is also exported from [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts) for programmatic SDK usage.