{"record":{"id":"9e2de5db4c3b9024","repo":"grafana/k6","slug":"error-while-parsing-selector-selector-unexp","errorCode":null,"errorMessage":"Error while parsing selector `${selector}` - unexpected symbol \"${next()}\" at position ${wp}","messagePattern":"Error while parsing selector `(.+?)` - unexpected symbol \"(.+?)\" at position (.+?)","errorType":"exception","errorClass":"InvalidSelectorError","httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/js/injected_script.js","lineNumber":990,"sourceCode":"// packages/playwright-core/src/utils/isomorphic/cssParser.ts\nvar InvalidSelectorError = class extends Error {\n};\n\n// packages/playwright-core/src/utils/isomorphic/selectorParser.ts\nfunction parseAttributeSelector(selector, allowUnquotedStrings) {\n  let wp = 0;\n  let EOL = selector.length === 0;\n  const next = () => selector[wp] || \"\";\n  const eat1 = () => {\n    const result2 = next();\n    ++wp;\n    EOL = wp >= selector.length;\n    return result2;\n  };\n  const syntaxError = (stage) => {\n    if (EOL)\n      throw new InvalidSelectorError(`Unexpected end of selector while parsing selector \\`${selector}\\``);\n    throw new InvalidSelectorError(`Error while parsing selector \\`${selector}\\` - unexpected symbol \"${next()}\" at position ${wp}` + (stage ? \" during \" + stage : \"\"));\n  };\n  function skipSpaces() {\n    while (!EOL && /\\s/.test(next()))\n      eat1();\n  }\n  function isCSSNameChar(char) {\n    return char >= \"\\x80\" || char >= \"0\" && char <= \"9\" || char >= \"A\" && char <= \"Z\" || char >= \"a\" && char <= \"z\" || char >= \"0\" && char <= \"9\" || char === \"_\" || char === \"-\";\n  }\n  function readIdentifier() {\n    let result2 = \"\";\n    skipSpaces();\n    while (!EOL && isCSSNameChar(next()))\n      result2 += eat1();\n    return result2;\n  }\n  function readQuotedString(quote) {\n    let result2 = eat1();\n    if (result2 !== quote)","sourceCodeStart":972,"sourceCodeEnd":1008,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/js/modules/k6/browser/common/js/injected_script.js#L972-L1008","documentation":"Frame.Fill() in the k6 browser module (internal/js/modules/k6/browser/common/frame.go:932) wraps every failure of the underlying fill action with 'filling %q with %q'. The action first waits for an element matching the selector to reach the attached state (respecting Timeout, default ~30s) and then calls the element's fill, which requires an <input>, <textarea>, or contenteditable element. Any timeout, strict-mode violation, or element-type failure is surfaced inside this wrapper.","triggerScenarios":"Selector matches nothing within opts.Timeout (default 30s, or the value set at launch/Context options); selector matches multiple elements with Strict:true; target element exists but is not an input/textarea/contenteditable (handle.fill returns a node-type error); element or its frame is detached mid-action (navigation during fill).","commonSituations":"Selectors written against one environment (data-testid present) failing on another; SPAs rendering inputs asynchronously after data fetches, so the element appears later than the timeout; iframes re-rendering during the fill; using Fill on a div or custom widget that only looks like an input.","solutions":["Verify the selector matches exactly one element: add data-testid attributes or use more specific selectors, and prefer page/frame locator APIs.","Wait for the element before filling: await page.waitForSelector(sel, { state: 'visible' }) or locator(sel).waitFor().","Pass an explicit timeout that fits the app: page.fill(sel, value, { timeout: 60000 }).","If the control is a custom widget (not a real input), use click/type or frame.type instead of fill.","Run with K6_DEBUG=true (or --log-output) to see the wrapped inner error naming the real cause."],"exampleFix":"// before\nawait page.fill('#username', 'alice');\n\n// after\nconst user = page.locator('#username');\nawait user.waitFor({ state: 'visible', timeout: 10000 });\nawait user.fill('alice');","handlingStrategy":"try-catch","validationCode":"const sel = '#username';\nconst found = await page.waitForSelector(sel, { state: 'visible', timeout: 5000 });\nif (!found) throw new Error('username field not rendered');","typeGuard":null,"tryCatchPattern":"try {\n  await page.fill(sel, value, { timeout: 10000 });\n} catch (e) {\n  const msg = String(e);\n  if (msg.includes('timed out')) throw new Error(`field ${sel} never appeared`);\n  if (msg.includes('input element')) throw new Error(`${sel} is not fillable; use type()`);\n  throw e;\n}","preventionTips":["Prefer locators: const loc = page.locator(sel); await loc.waitFor(); await loc.fill(v).","Add data-testid attributes in the app under test for stable selectors.","Set explicit per-action timeouts sized to the app's render time instead of relying on the 30s default."],"tags":["k6","browser","frame","fill","selector","timeout"],"backgroundTag":"element-not-found-timeout","analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}