{"record":{"id":"448fc904deedb23e","repo":"microsoft/playwright","slug":"multiple-directories-are-not-supported","errorCode":null,"errorMessage":"Multiple directories are not supported","messagePattern":"Multiple directories are not supported","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/client/elementHandle.ts","lineNumber":270,"sourceCode":"  if (isString(values[0]))\n    return { options: (values as string[]).map(valueOrLabel => ({ valueOrLabel })) };\n  return { options: values as SelectOption[] };\n}\n\ntype SetInputFilesFiles = Pick<channels.ElementHandleSetInputFilesParams, 'payloads' | 'localPaths' | 'localDirectory' | 'streams' | 'directoryStream'>;\n\nfunction filePayloadExceedsSizeLimit(payloads: FilePayload[]) {\n  return payloads.reduce((size, item) => size + (item.buffer ? item.buffer.byteLength : 0), 0) >= fileUploadSizeLimit;\n}\n\nasync function resolvePathsAndDirectoryForInputFiles(items: string[]): Promise<[string[] | undefined, string | undefined]> {\n  let localPaths: string[] | undefined;\n  let localDirectory: string | undefined;\n  for (const item of items) {\n    const stat = await fs.promises.stat(item as string);\n    if (stat.isDirectory()) {\n      if (localDirectory)\n        throw new Error('Multiple directories are not supported');\n      localDirectory = path.resolve(item as string);\n    } else {\n      localPaths ??= [];\n      localPaths.push(path.resolve(item as string));\n    }\n  }\n  if (localPaths?.length && localDirectory)\n    throw new Error('File paths must be all files or a single directory');\n  return [localPaths, localDirectory];\n}\n\nexport async function convertInputFiles(files: string | FilePayload | string[] | FilePayload[], context: BrowserContext): Promise<SetInputFilesFiles> {\n  const items: (string | FilePayload)[] = Array.isArray(files) ? files.slice() : [files];\n\n  if (items.some(item => typeof item === 'string')) {\n    if (!items.every(item => typeof item === 'string'))\n      throw new Error('File paths cannot be mixed with buffers');\n","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/client/elementHandle.ts#L252-L288","documentation":"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.","triggerScenarios":"Passing an array containing two or more directory paths: elementHandle.setInputFiles(['/dirA', '/dirB']) or page.setInputFiles(['./folder1', './folder2', 'a.txt']).","commonSituations":"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.","solutions":["Pass at most one directory path; if you need files from multiple directories, expand them to file paths first.","Validate the list up front: ensure ≤1 entry is a directory before calling setInputFiles.","For uploading a tree, zip the directories or concat their file lists into a single flat array of file paths."],"exampleFix":"// before\nawait locator.setInputFiles(['/data/folderA', '/data/folderB']);\n\n// after — expand to file paths\nconst { readdirSync, statSync } = require('node:fs');\nconst { join } = require('node:path');\nconst expand = d => readdirSync(d).flatMap(f => { const p = join(d,f); return statSync(p).isDirectory() ? expand(p) : [p]; });\nawait locator.setInputFiles([...expand('/data/folderA'), ...expand('/data/folderB')]);","handlingStrategy":"validation","validationCode":"import { statSync } from 'node:fs';\nfunction validateInputPaths(items: string[]) {\n  const dirs = items.filter(p => { try { return statSync(p).isDirectory(); } catch { return false; } });\n  if (dirs.length > 1) throw new Error(`Provide at most one directory; got ${dirs.length}: ${dirs.join(', ')}`);\n  return items;\n}","typeGuard":"import { statSync } from 'node:fs';\nfunction isDir(p: string): boolean { try { return statSync(p).isDirectory(); } catch { return false; } }","tryCatchPattern":null,"preventionTips":["Pre-validate the path list before setInputFiles.","Expand directories to file lists when you need files from multiple folders.","Document the single-directory rule at the upload site."],"tags":["file-upload","validation","input-files"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}