{"record":{"id":"3b51f3789d759e41","repo":"grafana/k6","slug":"setting-input-files-w","errorCode":null,"errorMessage":"setting input files: %w","messagePattern":"setting input files: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/element_handle.go","lineNumber":1465,"sourceCode":"\t\t[]string{}, selectText, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,\n\t)\n\tif _, err := call(h.ctx, selectTextAction, opts.Timeout); err != nil {\n\t\treturn fmt.Errorf(\"selecting text: %w\", err)\n\t}\n\n\tapplySlowMo(h.ctx)\n\n\treturn nil\n}\n\n// SetInputFiles sets the given files into the input file element.\nfunc (h *ElementHandle) SetInputFiles(files *Files, opts *ElementHandleSetInputFilesOptions) error {\n\tsetInputFiles := func(apiCtx context.Context, handle *ElementHandle) (any, error) {\n\t\treturn nil, handle.setInputFiles(apiCtx, files)\n\t}\n\tsetInputFilesAction := h.newAction([]string{}, setInputFiles, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout)\n\tif _, err := call(h.ctx, setInputFilesAction, opts.Timeout); err != nil {\n\t\treturn fmt.Errorf(\"setting input files: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (h *ElementHandle) setInputFiles(apiCtx context.Context, files *Files) error {\n\t// allow clearing the input by passing an empty array\n\tvar payload []*File\n\tif files != nil {\n\t\tpayload = files.Payload\n\t}\n\tfn := `\n\t\t(node, injected, payload) => {\n\t\t\treturn injected.setInputFiles(node, payload);\n\t\t}\n\t`\n\tevalOpts := evalOptions{\n\t\tforceCallable: true,","sourceCodeStart":1447,"sourceCodeEnd":1483,"githubUrl":"https://github.com/grafana/k6/blob/3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee/internal/js/modules/k6/browser/common/element_handle.go#L1447-L1483","documentation":"Thrown by the k6 browser module's ElementHandle.setInputFiles(). It wraps any failure of the setInputFiles action: timeout, element detached, or the injected script returning a DOM error — most typically 'node is not an input[type=file] element' (error:notfile) or 'non-multiple file input can only accept single file' (error:notmultiplefileinput).","triggerScenarios":"Calling el.setInputFiles(...) on an <input> that is not type=file; passing multiple files in the payload to an <input> without the multiple attribute; the file input being re-created by the framework and the handle going stale; timeout before the element is actionable.","commonSituations":"Drag-and-drop styled upload widgets that hide the real <input type=file> behind a button — developers select the visible button instead of the hidden input; React re-rendering the upload control after a failed upload, detaching the old handle.","solutions":["Target the real file input: const input = await page.waitForSelector('input[type=file]') — often hidden, so use page.waitForSelector with state 'attached' and then call setInputFiles (it works on hidden inputs).","Pass exactly one file when the input lacks the multiple attribute.","Re-query the handle right before the call so it is attached to the current DOM.","Increase the timeout: el.setInputFiles(files, { timeout: '60s' })."],"exampleFix":"// before\nconst btn = await page.$('.upload-button');\nawait btn.setInputFiles([{ name: 'a.png', mimeType: 'image/png', data: ... }]); // not a file input\n\n// after\nconst input = await page.waitForSelector('input[type=\"file\"]');\nawait input.setInputFiles([{ name: 'a.png', mimeType: 'image/png', data: pngBytes }], { timeout: '30s' });","handlingStrategy":"validation","validationCode":"const isFileInput = await el.evaluate(n => n.tagName === 'INPUT' && n.type === 'file');\nif (!isFileInput) {\n  throw new Error('setInputFiles target must be input[type=file]');\n}\nconst multiple = await el.evaluate(n => n.multiple);\nif (!multiple && files.length > 1) {\n  throw new Error('input lacks multiple attribute; pass a single file');\n}\nawait el.setInputFiles(files, { timeout: '30s' });","typeGuard":"async function isFileInput(el) {\n  if (!el) return false;\n  return await el.evaluate(n => n instanceof HTMLInputElement && n.type === 'file').catch(() => false);\n}","tryCatchPattern":"try {\n  await el.setInputFiles(files, { timeout: '30s' });\n} catch (e) {\n  if (String(e).includes('not an input[type=file]')) {\n    const input = await page.waitForSelector('input[type=\"file\"]');\n    await input.setInputFiles(files, { timeout: '30s' });\n  } else { throw e; }\n}","preventionTips":["Always locate the hidden input[type=file] of upload widgets rather than the visible upload button.","Check the multiple attribute before passing several files."],"tags":["k6","browser","element-handle","file-upload","wrong-element-type"],"backgroundTag":"element-wrong-type","analyzedSha":"3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}