microsoft/playwright · error · Error
File paths cannot be mixed with buffers
Error message
File paths cannot be mixed with buffers
What it means
Thrown by convertInputFiles when items contains at least one string (file path) but not every item is a string — i.e. the array mixes string paths with FilePayload (buffer) objects. The path-resolution branch requires all entries to be strings, so a mixed list is rejected before any filesystem access.
Source
Thrown at packages/playwright-core/src/client/elementHandle.ts:287
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');
const [localPaths, localDirectory] = await resolvePathsAndDirectoryForInputFiles(items);
if (context._connection.isRemote()) {
const files = localDirectory ? (await fs.promises.readdir(localDirectory, { withFileTypes: true, recursive: true })).filter(f => f.isFile()).map(f => path.join(f.parentPath, f.name)) : localPaths!;
const { writableStreams, rootDir } = await context._wrapApiCall(async () => context._channel.createTempFiles({
rootDirName: localDirectory ? path.basename(localDirectory) : undefined,
items: await Promise.all(files.map(async file => {
const lastModifiedMs = (await fs.promises.stat(file)).mtimeMs;
return {
name: localDirectory ? path.relative(localDirectory, file) : path.basename(file),
lastModifiedMs
};
})),
}, kNoTimeout), { internal: true });
for (let i = 0; i < files.length; i++) {
const writable = WritableStream.from(writableStreams[i]);
await stream.promises.pipeline(fs.createReadStream(files[i]), writable.stream());View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Use either all string paths or all FilePayload objects in a single call.
- Normalize mixed input up front: read disk files into FilePayload buffers, or write buffers to temp files and pass paths.
- Split into two setInputFiles calls if the element genuinely needs both (rare).
Example fix
// before
await locator.setInputFiles([
{ name: 'a.txt', mimeType: 'text/plain', buffer: Buffer.from('hi') },
'/tmp/b.txt',
]);
// after — all buffers
await locator.setInputFiles([
{ name: 'a.txt', mimeType: 'text/plain', buffer: Buffer.from('hi') },
{ name: 'b.txt', mimeType: 'text/plain', buffer: await fs.promises.readFile('/tmp/b.txt') },
]); Defensive patterns
Strategy: type-guard
Validate before calling
// Normalize a mixed list into either all-paths or all-payloads before setInputFiles.
function normalizeInputFiles(files) {
const hasString = files.some(f => typeof f === 'string');
const hasPayload = files.some(f => typeof f === 'object' && f !== null);
if (hasString && hasPayload)
throw new Error('File paths cannot be mixed with buffers; choose one form.');
return files;
} Type guard
type FilePayload = { name: string; mimeType?: string; buffer: Buffer };
type InputItem = string | FilePayload;
function isPayload(x: InputItem): x is FilePayload { return typeof x === 'object' && x !== null && 'buffer' in x; }
function isPath(x: InputItem): x is string { return typeof x === 'string'; }
function assertUniform(items: InputItem[]): 'paths' | 'payloads' {
const allPaths = items.every(isPath);
const allPayloads = items.every(isPayload);
if (!allPaths && !allPayloads)
throw new Error('File paths cannot be mixed with buffers');
return allPaths ? 'paths' : 'payloads';
} Prevention
- Pick one representation (paths or payloads) up front and stick to it.
- Read disk files into buffers only if you also convert all other entries.
- Validate uniformity before the API call.
When it happens
Trigger: Calling setInputFiles([{ name: 'a.txt', buffer: Buffer.from('...') }, '/tmp/b.txt']) — some entries are FilePayload objects, others are path strings.
Common situations: Building an upload list from mixed sources (some files on disk, some in memory); passing a single-element array where the single element is a payload alongside a path elsewhere; merging user input without normalization.
Related errors
- Multiple directories are not supported
- File paths must be all files or a single directory
- Exactly one of payloads, localPaths and streams must be prov
- Cannot set buffer larger than 50Mb, please write it to a fil
- localPaths are not allowed when the client is not local
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/9f8bf79c4feee4fa.
Report an issue: GitHub.