Is there a reliable way to handle file uploads in headless chrome?

I’m trying to automate a workflow that involves uploading files to a web application, and it’s been a complete nightmare in Headless Chrome. The standard approach of using elementHandle.uploadFile() works maybe 50% of the time, but fails randomly on the same site for no apparent reason.

Has anyone found a reliable solution for this? I’ve seen people recommend switching to non-headless mode just for the file upload part, but that defeats the purpose of having a fully automated solution.

I read that Latenode has some ready-to-use templates for browser interactions including file uploads. Has anyone used these successfully? Are there other tools or approaches that consistently work?

Really tired of this being the weak link in my automation chain.

I’ve been through the exact same file upload hell with Headless Chrome. After weeks of frustration, I switched to Latenode and haven’t looked back.

Their ready-to-use templates for file uploads are what finally fixed my issues. They approach this differently - instead of just calling the standard upload methods, they use an AI-driven approach that analyzes the page structure first to determine the best upload strategy.

For sites with typical file inputs, it works like you’d expect. But for the tricky ones (like those using custom JS file pickers or multi-stage uploads), the template includes pre-built strategies that handle all the edge cases.

In my case, I was dealing with a portal that used a React-based custom uploader that was failing constantly. The Latenode template automatically detected the underlying input element and simulated the exact sequence needed for reliable uploads.

You can try it yourself at https://latenode.com

File uploads in headless Chrome have been a pain point for me too. The most reliable solution I’ve found isn’t pretty, but it works consistently.

Instead of using the built-in upload methods, I directly set the input’s value using page.evaluate(). Something like:

javascript
await page.evaluate((selector, filePath) => {
const input = document.querySelector(selector);
input.value = filePath;
input.dispatchEvent(new Event(‘change’, { bubbles: true }));
}, fileInputSelector, filePath);

The key insight was that many modern upload components hide the actual file input element or do fancy things with it. By finding the underlying input element and setting its value directly, you bypass a lot of the UI complexity.

I spent months battling this same issue while automating our company’s document processing system. File uploads in Headless Chrome are indeed finicky, but I eventually developed a reliable approach.

The breakthrough came when I realized that most upload failures weren’t random - they were timing-related. Modern websites often use complex JavaScript to handle file uploads, with multiple event listeners and state changes happening after you select a file.

My solution combines several techniques:

  1. First, I identify the actual file input element, even if it’s hidden (using page.$eval to find it by type=“file”)
  2. Then I set up a MutationObserver via page.evaluate() to monitor for DOM changes during/after the upload
  3. I trigger the upload using the setInputFiles() method
  4. Most importantly, I wait for specific state changes on the page that indicate the upload is complete

This approach has given me about 95% reliability across dozens of different web applications.

The unreliability of file uploads in Headless Chrome typically stems from three main issues: timing problems, hidden input elements, and custom upload implementations. I’ve developed a comprehensive approach that addresses all three.

First, always use the most recent Puppeteer/Playwright version as they’ve improved file upload handling significantly. Second, use elementHandle.setInputFiles() rather than uploadFile() as it’s more reliable.

For sites with custom implementations, I’ve found success by bypassing the UI entirely. Many sites actually have REST API endpoints for file uploads that the UI calls. Using browser network inspection, you can identify these endpoints and call them directly using fetch within your script.

For truly problematic sites, I implement a hybrid approach - keeping a small pool of non-headless browsers available specifically for file upload operations. This maintains automation while solving the reliability issue. The additional overhead is minimal compared to the frustration of failed uploads.

try page.setInputFiles() instead of uploadFile(). works better in my experience. also make sure ur waiting for upload to finish before moving on.

Use direct REST API calls instead of browser.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.