{"record":{"id":"3c696787865b6125","repo":"microsoft/playwright","slug":"exactly-one-of-payloads-localpaths-and-streams-mu","errorCode":null,"errorMessage":"Exactly one of payloads, localPaths and streams must be provided","messagePattern":"Exactly one of payloads, localPaths and streams must be provided","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/fileUploadUtils.ts","lineNumber":43,"sourceCode":"import type * as types from './types';\nimport type * as channels from './channels';\n\n// Keep in sync with the client.\nexport const fileUploadSizeLimit = 50 * 1024 * 1024;\n\nasync function filesExceedUploadLimit(files: string[]) {\n  const sizes = await Promise.all(files.map(async file => (await fs.promises.stat(file)).size));\n  return sizes.reduce((total, size) => total + size, 0) >= fileUploadSizeLimit;\n}\n\nexport async function prepareFilesForUpload(frame: Frame, params: Omit<channels.ElementHandleSetInputFilesParams, 'timeout'>): Promise<InputFilesItems> {\n  const { payloads, streams, directoryStream } = params;\n  let { localPaths, localDirectory } = params;\n  if (localPaths && !frame.attribution.playwright.options.isClientCollocatedWithServer)\n    throw new Error('localPaths are not allowed when the client is not local');\n\n  if ([payloads, localPaths, localDirectory, streams, directoryStream].filter(Boolean).length !== 1)\n    throw new Error('Exactly one of payloads, localPaths and streams must be provided');\n\n  if (streams)\n    localPaths = streams.map(c => (c as WritableStreamDispatcher).path());\n  if (directoryStream)\n    localDirectory = (directoryStream as WritableStreamDispatcher).path();\n\n  if (localPaths) {\n    for (const p of localPaths)\n      assert(path.isAbsolute(p) && path.resolve(p) === p, 'Paths provided to localPaths must be absolute and fully resolved.');\n  }\n\n  let fileBuffers: {\n    name: string,\n    mimeType?: string,\n    buffer: Buffer,\n    lastModifiedMs?: number,\n  }[] | undefined = payloads;\n","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/fileUploadUtils.ts#L25-L61","documentation":"prepareFilesForUpload requires exactly one source of input files. It counts the truthy values among payloads, localPaths, localDirectory, streams, and directoryStream and throws if the count is not exactly 1 - i.e. zero provided or more than one provided at once.","triggerScenarios":"Calling setInputFiles with no arguments, with multiple mutually-exclusive source types at once, or with an empty/undefined combination. Also reached internally if a dispatcher forwards two populated fields.","commonSituations":"Migrating between path-based and payload-based uploads and accidentally leaving both; calling setInputFiles() with an empty array; passing both streams and payloads in a custom integration.","solutions":["Pass exactly one source: a single paths array, OR a single payloads array, OR a single directory.","Clear stale fields when refactoring from one input mode to another.","If clearing files is the goal, use setInputFiles([]) explicitly via the dedicated path rather than ambiguous params."],"exampleFix":"// before\nawait handle.setInputFiles(); // nothing -> throws\n// after: pick exactly one\nawait handle.setInputFiles(['/abs/file.pdf']);\n// or\nawait handle.setInputFiles([{ name: 'f.pdf', mimeType: 'application/pdf', buffer }]);","handlingStrategy":"validation","validationCode":"// Enforce exactly-one before calling\nfunction oneOf<T>(...vals: (T | undefined)[]): boolean {\n  return vals.filter(v => v !== undefined && v !== null).length === 1;\n}\nif (!oneOf(paths, payloads)) throw new Error('specify exactly one source');","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Treat the input sources as an enum; never combine them.","Add a wrapper that asserts the cardinality once."],"tags":["file-upload","validation","input-files"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}