{"record":{"id":"44ef49d48fe93b94","repo":"grafana/k6","slug":"evaluate-requires-a-page-function-44ef49","errorCode":null,"errorMessage":"evaluate requires a page function","messagePattern":"evaluate requires a page function","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/page_mapping.go","lineNumber":107,"sourceCode":"\t\t\t}), nil\n\t\t},\n\t\t\"emulateMedia\": func(opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts, err := parsePageEmulateMediaOptions(rt, opts, common.NewPageEmulateMediaOptions(p))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing emulateMedia options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, p.EmulateMedia(popts) //nolint:wrapcheck\n\t\t\t}), nil\n\t\t},\n\t\t\"emulateVisionDeficiency\": func(typ string) *sobek.Promise {\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, p.EmulateVisionDeficiency(typ) //nolint:wrapcheck\n\t\t\t})\n\t\t},\n\t\t\"evaluate\": func(pageFunc sobek.Value, gargs ...sobek.Value) (*sobek.Promise, error) {\n\t\t\tif sobekEmptyString(pageFunc) {\n\t\t\t\treturn nil, fmt.Errorf(\"evaluate requires a page function\")\n\t\t\t}\n\t\t\tfuncString := pageFunc.String()\n\t\t\tgopts := exportArgs(gargs)\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn p.Evaluate(funcString, gopts...)\n\t\t\t}), nil\n\t\t},\n\t\t\"evaluateHandle\": func(pageFunc sobek.Value, gargs ...sobek.Value) (*sobek.Promise, error) {\n\t\t\tif sobekEmptyString(pageFunc) {\n\t\t\t\treturn nil, fmt.Errorf(\"evaluateHandle requires a page function\")\n\t\t\t}\n\t\t\tfuncString := pageFunc.String()\n\t\t\tgopts := exportArgs(gargs)\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\tjsh, err := p.EvaluateHandle(funcString, gopts...)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err //nolint:wrapcheck\n\t\t\t\t}","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/grafana/k6/blob/8d06114777191d21ef885d05c5f8aa9e1ed838ae/internal/js/modules/k6/browser/browser/page_mapping.go#L89-L125","documentation":"Thrown synchronously by page.evaluate(pageFunc, ...args) when the first argument is nullish, empty, or whitespace-only. The guard sobekEmptyString (internal/js/modules/k6/browser/browser/helpers.go:66-68) treats undefined, null and any string that trims to empty as missing. The check happens before the promise is created, so the call throws immediately and no browser code runs.","triggerScenarios":"page.evaluate('') or page.evaluate('   '); page.evaluate(null) / page.evaluate(undefined); passing a variable that was never assigned or an optional-chaining result; template literals that render empty, e.g. page.evaluate(``); calling page.evaluate() with no arguments at all.","commonSituations":"Selecting a function at runtime (desktop vs mobile handler) and picking an undefined branch; passing a function name that is misspelled so JS yields undefined; building the page function from empty config strings.","solutions":["Pass a function: page.evaluate(() => document.title)","If the function comes from a variable, verify it before the call: if (!fn || (typeof fn === 'string' && !fn.trim())) throw new Error('...')","Check for typos or missing imports on the variable you are passing"],"exampleFix":"// before\nconst fn = handlers[mode];        // undefined when mode is unknown\nawait page.evaluate(fn);\n// evaluate requires a page function\n\n// after\nconst fn = handlers[mode];\nif (!fn) throw new Error(`no handler for mode ${mode}`);\nawait page.evaluate(fn);","handlingStrategy":"validation","validationCode":"function requirePageFunc(fn) {\n  if (fn === undefined || fn === null) throw new Error('page function is required');\n  if (typeof fn === 'string' && fn.trim() === '') throw new Error('page function string is empty');\n  if (typeof fn !== 'function' && typeof fn !== 'string') throw new Error('page function must be a function or string');\n  return fn;\n}\nawait page.evaluate(requirePageFunc(userFunc), ...args);","typeGuard":"/** @param {unknown} fn */\nfunction isPageFunc(fn) {\n  if (typeof fn === 'function') return true;\n  return typeof fn === 'string' && fn.trim().length > 0;\n}","tryCatchPattern":"try {\n  await page.evaluate(userFunc, ...args);\n} catch (e) {\n  if (String(e).includes('evaluate requires a page function')) {\n    console.warn(`evaluate called with missing function (${name}); skipping`);\n  } else throw e;\n}","preventionTips":["Prefer passing functions over serialized strings","Guard dynamically selected handlers with an existence check before the call","Add a smoke test that asserts every entry in a handler map is defined"],"tags":["k6","browser","page","evaluate","missing-argument"],"backgroundTag":"missing-function-argument","analyzedSha":"8d06114777191d21ef885d05c5f8aa9e1ed838ae","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}