microsoft/playwright · error · Error
At least one of "paths" or "data" must be provided.
Error message
At least one of "paths" or "data" must be provided.
What it means
Thrown by the browser_drop tool when params.paths is empty/undefined AND params.data is undefined. The tool's contract is that at least one payload source (filesystem paths or a MIME→value data map) must be supplied to construct the drag-drop event.
Source
Thrown at packages/playwright-core/src/tools/backend/files.ts:73
});
export const drop = defineTabTool({
capability: 'core',
schema: {
name: 'browser_drop',
title: 'Drop files or data onto an element',
description: 'Drop files or MIME-typed data onto an element, as if dragged from outside the page. At least one of "paths" or "data" must be provided.',
inputSchema: elementSchema.extend({
paths: z.array(z.string()).optional().describe('Absolute paths to files to drop onto the element.'),
data: z.record(z.string(), z.string()).optional().describe('Data to drop, as a map of MIME type to string value (e.g. {"text/plain": "hello", "text/uri-list": "https://example.com"}).'),
}),
type: 'action',
},
handle: async (tab, params, response) => {
if (!params.paths?.length && !params.data)
throw new Error('At least one of "paths" or "data" must be provided.');
response.setIncludeSnapshot();
const { locator, resolved } = await tab.targetLocator(params);
if (params.paths)
await Promise.all(params.paths.map(p => response.resolveClientFilename(p)));
const payload: { files?: string | string[], data?: Record<string, string> } = {};
if (params.paths?.length)
payload.files = params.paths.length === 1 ? params.paths[0] : params.paths;
if (params.data)
payload.data = params.data;
await tab.waitForCompletion(async () => {
await locator.drop(payload, tab.actionTimeoutOptions);
});
response.addCode(`await page.${resolved}.drop(${formatObject(payload)});`);View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Provide at least one absolute path in params.paths.
- Or provide params.data as a Record<string,string> of MIME type to value (e.g. {"text/plain":"hello"}).
- Validate payload before the call: assert paths?.length || data.
Example fix
// before
await client.callTool('browser_drop', { element: 'dropzone', ref: 'e2' }); // throws
// after
await client.callTool('browser_drop', {
element: 'dropzone', ref: 'e2',
data: { 'text/plain': 'hello world' }
}); Defensive patterns
Strategy: validation
Validate before calling
function validateDropParams(p: { paths?: string[]; data?: Record<string,string> }) {
if (!p.paths?.length && !p.data)
throw new Error('browser_drop requires paths or data');
}
validateDropParams(params);
await client.callTool('browser_drop', params); Type guard
function hasDropPayload(p: { paths?: unknown[]; data?: object }): boolean {
return (!!p.paths && p.paths.length > 0) || (!!p.data && Object.keys(p.data).length > 0);
} Try / catch
try {
await client.callTool('browser_drop', params);
} catch (e) {
if (e instanceof Error && e.message.startsWith('At least one of "paths" or "data"')) {
// supply a default data payload or ask the caller
} else throw e;
} Prevention
- Because both fields are .optional() in zod, validate the 'one required' rule in your caller.
- Default to a text/plain data payload when you only need to drop text content.
- Use absolute paths for files; relative paths may also fail downstream resolution.
When it happens
Trigger: Invoking browser_drop with an empty paths array and no data, or omitting both fields entirely (both are .optional() in the schema, so zod does not catch the emptiness).
Common situations: Agent defaulting to {} for an optional-looking tool; building the payload conditionally and ending with neither branch populated.
Related errors
- Invalid location "${params.location}", expected format is <f
- fullPage cannot be used with element screenshots.
- Tab index is required
- Either time, text or textGone must be provided
- Video recording has already been started.
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/8936d3c5298e8499.
Report an issue: GitHub.