{"record":{"id":"8f54721fa18a2293","repo":"puppeteer/puppeteer","slug":"element-cannot-be-filled-out","errorCode":null,"errorMessage":"Element cannot be filled out.","messagePattern":"Element cannot be filled out\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/puppeteer-core/src/api/locators/locators.ts","lineNumber":611,"sourceCode":"                          (input as HTMLInputElement).value = '';\n                          (input as HTMLInputElement).value = currentValue;\n                        }\n                        return valString.substring(currentValue.length);\n                      }, value),\n                    ).pipe(\n                      mergeMap(textToType => {\n                        if (!textToType) {\n                          return of(undefined);\n                        }\n                        return from(handle.type(textToType));\n                      }),\n                    );\n                  }\n                  return fillDirectly();\n                case 'other-input':\n                  return fillDirectly();\n                case 'unknown':\n                  throw new Error(`Element cannot be filled out.`);\n              }\n            }),\n          )\n          .pipe(\n            catchError(err => {\n              void handle.dispose().catch(error => {\n                this.#logger?.(DEBUG_PREFIXES.error)?.(error);\n              });\n              throw err;\n            }),\n          );\n      }),\n      this.operators.retryAndRaceWithSignalAndTimer(signal, cause),\n    );\n  }\n\n  #hover<ElementType extends Element>(\n    this: Locator<ElementType>,","sourceCodeStart":593,"sourceCodeEnd":629,"githubUrl":"https://github.com/puppeteer/puppeteer/blob/d484e21c17f6023826fefdcdeeb553e04a7aaed8/packages/puppeteer-core/src/api/locators/locators.ts#L593-L629","documentation":"Thrown by Locator.fill() when the target element is classified as an 'unknown' input type that Puppeteer cannot fill. The locator first categorizes the element (checkable-input, select, contenteditable, typeable-input, other-input, unknown); only 'unknown' throws, meaning the element is neither a recognizable form control nor editable content.","triggerScenarios":"Calling `page.locator('div#label').fill('text')` on a non-input, non-editable element such as a plain div, span, or image. Also triggered on custom elements that don't expose a value or contentEditable interface.","commonSituations":"Selector matches a wrapper/container instead of the actual input; shadow-DOM custom element that Puppeteer can't introspect; wrong locator target after a DOM refactor.","solutions":["Point the locator at a real fillable element: input, textarea, select, or a contentEditable node.","If you must set text on a non-input, use `locator.evaluate((el, v) => { el.textContent = v; }, value)` instead.","For custom elements, expose a value or make them contentEditable so the locator recognizes them."],"exampleFix":"// before\nawait page.locator('div.greeting').fill('hello');\n// after\nawait page.locator('input#name').fill('hello');","handlingStrategy":"validation","validationCode":"const tag = await el.evaluate(node => node.tagName.toLowerCase());\nif (!['input', 'textarea', 'select'].includes(tag) &&\n    !(await el.evaluate(n => (n as HTMLElement).isContentEditable))) {\n  throw new Error('element is not fillable');\n}\nawait page.locator(sel).fill('text');","typeGuard":"async function isFillable(el: ElementHandle): Promise<boolean> {\n  return el.evaluate(node => {\n    const n = node as HTMLElement;\n    return ['INPUT', 'TEXTAREA', 'SELECT'].includes(n.tagName) || n.isContentEditable;\n  });\n}","tryCatchPattern":"try {\n  await page.locator(sel).fill('text');\n} catch (e) {\n  if (e instanceof Error && /cannot be filled/.test(e.message)) {\n    await page.locator(sel).evaluate((el, v) => { (el as HTMLElement).textContent = v; }, 'text');\n  } else throw e;\n}","preventionTips":["Verify the selector targets an actual input/textarea/select/contentEditable.","Use waitForSelector before fill to ensure the element exists and is laid out.","For custom elements, set value via evaluate instead of fill."],"tags":["locator","fill","validation","input-type"],"backgroundTag":null,"analyzedSha":"d484e21c17f6023826fefdcdeeb553e04a7aaed8","analyzedAt":"2026-08-12T06:33:19.665Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}