microsoft/playwright · error · Error

Multiple directories are not supported

Error message

Multiple directories are not supported

What it means

Thrown by resolvePathsAndDirectoryForInputFiles when a second directory is encountered while localDirectory is already set. setInputFiles supports either a list of file paths or exactly one directory — never more than one directory. As soon as the second directory is stat'd, the call rejects.

Source

Thrown at packages/playwright-core/src/client/elementHandle.ts:270

  if (isString(values[0]))
    return { options: (values as string[]).map(valueOrLabel => ({ valueOrLabel })) };
  return { options: values as SelectOption[] };
}

type SetInputFilesFiles = Pick<channels.ElementHandleSetInputFilesParams, 'payloads' | 'localPaths' | 'localDirectory' | 'streams' | 'directoryStream'>;

function filePayloadExceedsSizeLimit(payloads: FilePayload[]) {
  return payloads.reduce((size, item) => size + (item.buffer ? item.buffer.byteLength : 0), 0) >= fileUploadSizeLimit;
}

async function resolvePathsAndDirectoryForInputFiles(items: string[]): Promise<[string[] | undefined, string | undefined]> {
  let localPaths: string[] | undefined;
  let localDirectory: string | undefined;
  for (const item of items) {
    const stat = await fs.promises.stat(item as string);
    if (stat.isDirectory()) {
      if (localDirectory)
        throw new Error('Multiple directories are not supported');
      localDirectory = path.resolve(item as string);
    } else {
      localPaths ??= [];
      localPaths.push(path.resolve(item as string));
    }
  }
  if (localPaths?.length && localDirectory)
    throw new Error('File paths must be all files or a single directory');
  return [localPaths, localDirectory];
}

export async function convertInputFiles(files: string | FilePayload | string[] | FilePayload[], context: BrowserContext): Promise<SetInputFilesFiles> {
  const items: (string | FilePayload)[] = Array.isArray(files) ? files.slice() : [files];

  if (items.some(item => typeof item === 'string')) {
    if (!items.every(item => typeof item === 'string'))
      throw new Error('File paths cannot be mixed with buffers');

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Pass at most one directory path; if you need files from multiple directories, expand them to file paths first.
  2. Validate the list up front: ensure ≤1 entry is a directory before calling setInputFiles.
  3. For uploading a tree, zip the directories or concat their file lists into a single flat array of file paths.

Example fix

// before
await locator.setInputFiles(['/data/folderA', '/data/folderB']);

// after — expand to file paths
const { readdirSync, statSync } = require('node:fs');
const { join } = require('node:path');
const expand = d => readdirSync(d).flatMap(f => { const p = join(d,f); return statSync(p).isDirectory() ? expand(p) : [p]; });
await locator.setInputFiles([...expand('/data/folderA'), ...expand('/data/folderB')]);
Defensive patterns

Strategy: validation

Validate before calling

import { statSync } from 'node:fs';
function validateInputPaths(items: string[]) {
  const dirs = items.filter(p => { try { return statSync(p).isDirectory(); } catch { return false; } });
  if (dirs.length > 1) throw new Error(`Provide at most one directory; got ${dirs.length}: ${dirs.join(', ')}`);
  return items;
}

Type guard

import { statSync } from 'node:fs';
function isDir(p: string): boolean { try { return statSync(p).isDirectory(); } catch { return false; } }

Prevention

When it happens

Trigger: Passing an array containing two or more directory paths: elementHandle.setInputFiles(['/dirA', '/dirB']) or page.setInputFiles(['./folder1', './folder2', 'a.txt']).

Common situations: Globbing over a tree and passing all matched directories; user-provided path list that happens to contain two folders; misunderstanding that directory upload is single-directory only.

Related errors


AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12). Data as JSON: /api/errors/448fc904deedb23e. Report an issue: GitHub.