{"record":{"id":"8936d3c5298e8499","repo":"microsoft/playwright","slug":"at-least-one-of-paths-or-data-must-be-provided","errorCode":null,"errorMessage":"At least one of \"paths\" or \"data\" must be provided.","messagePattern":"At least one of \"paths\" or \"data\" must be provided\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/tools/backend/files.ts","lineNumber":73,"sourceCode":"});\n\nexport const drop = defineTabTool({\n  capability: 'core',\n\n  schema: {\n    name: 'browser_drop',\n    title: 'Drop files or data onto an element',\n    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.',\n    inputSchema: elementSchema.extend({\n      paths: z.array(z.string()).optional().describe('Absolute paths to files to drop onto the element.'),\n      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\"}).'),\n    }),\n    type: 'action',\n  },\n\n  handle: async (tab, params, response) => {\n    if (!params.paths?.length && !params.data)\n      throw new Error('At least one of \"paths\" or \"data\" must be provided.');\n\n    response.setIncludeSnapshot();\n    const { locator, resolved } = await tab.targetLocator(params);\n\n    if (params.paths)\n      await Promise.all(params.paths.map(p => response.resolveClientFilename(p)));\n\n    const payload: { files?: string | string[], data?: Record<string, string> } = {};\n    if (params.paths?.length)\n      payload.files = params.paths.length === 1 ? params.paths[0] : params.paths;\n    if (params.data)\n      payload.data = params.data;\n\n    await tab.waitForCompletion(async () => {\n      await locator.drop(payload, tab.actionTimeoutOptions);\n    });\n\n    response.addCode(`await page.${resolved}.drop(${formatObject(payload)});`);","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/tools/backend/files.ts#L55-L91","documentation":"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.","triggerScenarios":"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).","commonSituations":"Agent defaulting to {} for an optional-looking tool; building the payload conditionally and ending with neither branch populated.","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."],"exampleFix":"// before\nawait client.callTool('browser_drop', { element: 'dropzone', ref: 'e2' }); // throws\n\n// after\nawait client.callTool('browser_drop', {\n  element: 'dropzone', ref: 'e2',\n  data: { 'text/plain': 'hello world' }\n});","handlingStrategy":"validation","validationCode":"function validateDropParams(p: { paths?: string[]; data?: Record<string,string> }) {\n  if (!p.paths?.length && !p.data)\n    throw new Error('browser_drop requires paths or data');\n}\nvalidateDropParams(params);\nawait client.callTool('browser_drop', params);","typeGuard":"function hasDropPayload(p: { paths?: unknown[]; data?: object }): boolean {\n  return (!!p.paths && p.paths.length > 0) || (!!p.data && Object.keys(p.data).length > 0);\n}","tryCatchPattern":"try {\n  await client.callTool('browser_drop', params);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('At least one of \"paths\" or \"data\"')) {\n    // supply a default data payload or ask the caller\n  } else throw e;\n}","preventionTips":["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."],"tags":["drag-drop","input-validation","mcp-tool"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}