grafana/k6 · error
evaluateHandle requires a page function
Error message
evaluateHandle requires a page function
What it means
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.
Source
Thrown at internal/js/modules/k6/browser/browser/frame_mapping.go:83
}
earg := exportArg(eventInit)
return promise(vu, func() (any, error) {
return nil, f.DispatchEvent(selector, typ, earg, popts) //nolint:wrapcheck
}), nil
},
"evaluate": func(pageFunc sobek.Value, gargs ...sobek.Value) (*sobek.Promise, error) {
if sobekEmptyString(pageFunc) {
return nil, fmt.Errorf("evaluate requires a page function")
}
funcString := pageFunc.String()
gopts := exportArgs(gargs)
return promise(vu, func() (any, error) {
return f.Evaluate(funcString, gopts...)
}), nil
},
"evaluateHandle": func(pageFunc sobek.Value, gargs ...sobek.Value) (*sobek.Promise, error) {
if sobekEmptyString(pageFunc) {
return nil, fmt.Errorf("evaluateHandle requires a page function")
}
funcString := pageFunc.String()
gopts := exportArgs(gargs)
return promise(vu, func() (any, error) {
jsh, err := f.EvaluateHandle(funcString, gopts...)
if err != nil {
return nil, err //nolint:wrapcheck
}
return mapJSHandle(vu, jsh), nil
}), nil
},
"fill": func(selector, value string, opts sobek.Value) (*sobek.Promise, error) {
popts := common.NewFrameFillOptions(f.Timeout())
if err := popts.Parse(vu.Context(), opts); err != nil {
return nil, fmt.Errorf("parsing fill options: %w", err)
}
return promise(vu, func() (any, error) {
return nil, f.Fill(selector, value, popts) //nolint:wrapcheckView on GitHub (pinned to 93accf6570)
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 ''
Example fix
// before
let factory;
frame.evaluateHandle(factory);
// after
const factory = () => document.createElement('div');
frame.evaluateHandle(factory); Defensive patterns
Strategy: type-guard
Validate before calling
const fn = typeof pageFunc === 'function' ? pageFunc.toString()
: typeof pageFunc === 'string' ? pageFunc.trim() : '';
if (!fn) throw new Error('frame.evaluateHandle needs a non-empty function or string'); Type guard
function isUsablePageFunction(v) {
if (v == null) return false;
if (typeof v === 'function') return true;
return typeof v === 'string' && v.trim().length > 0;
} Try / catch
try {
const h = await frame.evaluateHandle(fn, ...args);
} catch (e) {
console.error(`evaluateHandle failed: ${e.message}`);
} Prevention
- 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
When it happens
Trigger: frame.evaluateHandle(undefined), frame.evaluateHandle(''), or a whitespace-only string/function variable; error is thrown synchronously before the promise is created.
Common situations: 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.
Related errors
- parsing new frame check options: %w
- parsing double click options: %w
- evaluate requires a page function
- parsing frame dispatch event options: %w
- parsing fill options: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/51b2a283deec12c9.
Report an issue: GitHub.