{"record":{"id":"aba263d512840826","repo":"grafana/k6","slug":"parsing-page-navigation-options-to-q-w","errorCode":null,"errorMessage":"parsing page navigation options to %q: %w","messagePattern":"parsing page navigation options to %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/page_mapping.go","lineNumber":241,"sourceCode":"\t\t\treturn rt.ToValue(ml).ToObject(rt), nil\n\t\t},\n\t\t\"getByText\": func(text sobek.Value, opts sobek.Value) (*sobek.Object, error) {\n\t\t\tif k6common.IsNullish(text) {\n\t\t\t\treturn nil, errors.New(\"missing required argument 'text'\")\n\t\t\t}\n\t\t\tptext, popts := parseGetByBaseOptions(vu.Context(), text, true, opts)\n\n\t\t\tml := mapLocator(vu, p.GetByText(ptext, popts))\n\t\t\treturn rt.ToValue(ml).ToObject(rt), nil\n\t\t},\n\t\t\"goto\": func(url string, opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tgopts, err := parseFrameGotoOptions(\n\t\t\t\trt, opts,\n\t\t\t\tp.Referrer(),\n\t\t\t\tp.NavigationTimeout(),\n\t\t\t)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing page navigation options to %q: %w\", url, err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\tresp, err := p.Goto(url, gopts)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err //nolint:wrapcheck\n\t\t\t\t}\n\n\t\t\t\treturn mapResponse(vu, resp), nil\n\t\t\t}), nil\n\t\t},\n\t\t\"hover\": func(selector string, opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts, err := parseFrameHoverOptions(rt, opts, p.MainFrame().Timeout())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing hover options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, p.Hover(selector, popts) //nolint:wrapcheck\n\t\t\t}), nil","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/grafana/k6/blob/8d06114777191d21ef885d05c5f8aa9e1ed838ae/internal/js/modules/k6/browser/browser/page_mapping.go#L223-L259","documentation":"Thrown synchronously by page.goto(url, opts) when FrameGotoOptions.Parse rejects an option. The failing branch is 'waitUntil': the string must unmarshal to a LifecycleEvent, and anything outside load, domcontentloaded, networkidle yields 'invalid lifecycle event: %q; must be one of: ...' (internal/js/modules/k6/browser/common/lifecycle.go:89-109), wrapped as 'parsing page navigation options to \"<url>\"'. referer and timeout are coerced and never fail. The URL is included in the message, which helps when navigating in a loop.","triggerScenarios":"page.goto(url, { waitUntil: 'networkIdle' }) — wrong casing, must be lowercase 'networkidle'; waitUntil: 'commit' or 'load' variants not in the enum such as 'interactive'; waitUntil: '' (empty string, e.g. from unset env var); waitUntil spelled 'domContentLoaded' instead of 'domcontentloaded'.","commonSituations":"Porting Puppeteer scripts ('networkidle2' is not accepted) or Playwright scripts ('commit' is not supported); waitUntil sourced from __ENV that is undefined; casing mistakes because the browser-module value differs from Playwright's camelCase constants.","solutions":["Use one of the three exact lowercase strings: 'load', 'domcontentloaded', 'networkidle'","If waitUntil comes from the environment, default it: const waitUntil = ['load','domcontentloaded','networkidle'].includes(__ENV.WAIT) ? __ENV.WAIT : 'load'","Check the URL in the message to find which navigation in a data-driven loop passed the bad option"],"exampleFix":"// before\nawait page.goto('https://k6.io', { waitUntil: 'networkIdle' });\n// parsing page navigation options to \"https://k6.io\": parsing goto options:\n// invalid lifecycle event: \"networkIdle\"; must be one of: load, domcontentloaded, networkidle\n\n// after\nawait page.goto('https://k6.io', { waitUntil: 'networkidle' });","handlingStrategy":"validation","validationCode":"const WAIT_UNTIL = new Set(['load', 'domcontentloaded', 'networkidle']);\nfunction normalizeWaitUntil(v) {\n  return WAIT_UNTIL.has(v) ? v : 'load';\n}\nawait page.goto(url, {\n  waitUntil: normalizeWaitUntil(__ENV.WAIT_UNTIL),\n  timeout: 30000,\n});","typeGuard":"/** @param {unknown} v */\nfunction isWaitUntil(v) {\n  return v === 'load' || v === 'domcontentloaded' || v === 'networkidle';\n}","tryCatchPattern":"try {\n  await page.goto(url, opts);\n} catch (e) {\n  if (String(e).includes('invalid lifecycle event')) {\n    console.warn(`bad waitUntil for ${url}; falling back to 'load'`);\n    await page.goto(url, { ...opts, waitUntil: 'load' });\n  } else throw e;\n}","preventionTips":["Only three exact lowercase values: load, domcontentloaded, networkidle","Puppeteer's networkidle2 and Playwright's commit are not supported","Default env-sourced waitUntil to 'load' instead of passing raw strings","Use the URL echoed in the message to find the failing navigation in loops"],"tags":["k6","browser","page","goto","wait-until","enum"],"backgroundTag":"invalid-waituntil-value","analyzedSha":"8d06114777191d21ef885d05c5f8aa9e1ed838ae","analyzedAt":"2026-09-14T20:10:14.619Z","contentChangedAt":"2026-09-14T20:10:14.619Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}