{"record":{"id":"51b2a283deec12c9","repo":"grafana/k6","slug":"evaluatehandle-requires-a-page-function","errorCode":null,"errorMessage":"evaluateHandle requires a page function","messagePattern":"evaluateHandle requires a page function","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/frame_mapping.go","lineNumber":83,"sourceCode":"\t\t\t}\n\t\t\tearg := exportArg(eventInit)\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, f.DispatchEvent(selector, typ, earg, popts) //nolint:wrapcheck\n\t\t\t}), nil\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 f.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 := f.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}\n\t\t\t\treturn mapJSHandle(vu, jsh), nil\n\t\t\t}), nil\n\t\t},\n\t\t\"fill\": func(selector, value string, opts sobek.Value) (*sobek.Promise, error) {\n\t\t\tpopts := common.NewFrameFillOptions(f.Timeout())\n\t\t\tif err := popts.Parse(vu.Context(), opts); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"parsing fill options: %w\", err)\n\t\t\t}\n\t\t\treturn promise(vu, func() (any, error) {\n\t\t\t\treturn nil, f.Fill(selector, value, popts) //nolint:wrapcheck","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/browser/frame_mapping.go#L65-L101","documentation":"frame.evaluateHandle(pageFunc, ...args) was called with a nullish, empty, or whitespace-only page function (frame_mapping.go:83, same sobekEmptyString check as evaluate). Unlike evaluate, evaluateHandle returns a JSHandle to an in-page object, but the input validation is identical: the serialized function string must be non-empty.","triggerScenarios":"frame.evaluateHandle(undefined), frame.evaluateHandle(''), or a whitespace-only string/function variable; error is thrown synchronously before the promise is created.","commonSituations":"Same as 429: empty template strings, unset variables, helper functions returning undefined; also code paths that branch between evaluate and evaluateHandle and forward a possibly-empty expression.","solutions":["Pass a concrete function: frame.evaluateHandle(() => document.body) or non-empty string","Validate the source before calling: if (typeof fn !== 'function' && !String(fn).trim()) fail fast with a clear message","Log the value being passed when this error appears - it is almost always undefined or ''"],"exampleFix":"// before\nlet factory;\nframe.evaluateHandle(factory);\n// after\nconst factory = () => document.createElement('div');\nframe.evaluateHandle(factory);","handlingStrategy":"type-guard","validationCode":"const fn = typeof pageFunc === 'function' ? pageFunc.toString()\n          : typeof pageFunc === 'string' ? pageFunc.trim() : '';\nif (!fn) throw new Error('frame.evaluateHandle needs a non-empty function or string');","typeGuard":"function isUsablePageFunction(v) {\n  if (v == null) return false;\n  if (typeof v === 'function') return true;\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try {\n  const h = await frame.evaluateHandle(fn, ...args);\n} catch (e) {\n  console.error(`evaluateHandle failed: ${e.message}`);\n}","preventionTips":["Verify helper factories return a function before forwarding to evaluateHandle","Prefer function expressions over string concatenation to avoid empty results","Share one page-function guard between evaluate and evaluateHandle"],"tags":["k6","browser","frame","evaluatehandle","javascript"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}