grafana/k6 · error
evaluating handle for frame: %w
Error message
evaluating handle for frame: %w
What it means
Frame.EvaluateHandle() resolves the main-world execution context and calls ec.EvalHandle. This error wraps that call's failure: the page function threw a JS exception, an argument failed to serialize into the context, or the context was destroyed during evaluation.
Source
Thrown at internal/js/modules/k6/browser/common/frame.go:919
// EvaluateHandle will evaluate provided page function within an execution context.
func (f *Frame) EvaluateHandle(pageFunc string, args ...any) (handle JSHandleAPI, _ error) {
f.log.Debugf("Frame:EvaluateHandle", "fid:%s furl:%q", f.ID(), f.URL())
evalHandle := func() (JSHandleAPI, error) {
f.executionContextMu.RLock()
defer f.executionContextMu.RUnlock()
ec := f.executionContexts[mainWorld]
if ec == nil {
return nil, fmt.Errorf("evaluating handle for frame: execution context %q not found", mainWorld)
}
return ec.EvalHandle(f.ctx, pageFunc, args...) //nolint:wrapcheck
}
f.waitForExecutionContext(mainWorld)
handle, err := evalHandle()
if err != nil {
return nil, fmt.Errorf("evaluating handle for frame: %w", err)
}
applySlowMo(f.ctx)
return handle, nil
}
// Fill fills out the first element found that matches the selector.
func (f *Frame) Fill(selector, value string, popts *FrameFillOptions) error {
f.log.Debugf("Frame:Fill", "fid:%s furl:%q sel:%q val:%q", f.ID(), f.URL(), selector, value)
if err := f.fill(selector, value, popts); err != nil {
return fmt.Errorf("filling %q with %q: %w", selector, value, err)
}
applySlowMo(f.ctx)
return nilView on GitHub (pinned to 93accf6570)
Solutions
- Make the function defensive: null-check before use and run it in DevTools first.
- Wait for the elements/state the function depends on (waitForSelector).
- Pass only serializable args and use a proper function expression ('() => ...').
Example fix
// before
const h = page.evaluateHandle('() => document.querySelector("#x").dataset'); // #x may be null
// after
await page.waitForSelector('#x', { state: 'attached' });
const h = page.evaluateHandle('() => document.querySelector("#x").dataset'); Defensive patterns
Strategy: try-catch
Validate before calling
await frame.waitForSelector(sel, { state: 'attached', timeout: 30000 }); // if pageFunc touches an element Try / catch
let h;
try {
h = frame.evaluateHandle(pageFunc, ...args);
} catch (e) {
console.warn('evaluateHandle failed:', e.message);
} Prevention
- Null-check DOM lookups inside the evaluated function.
- Keep args serializable; use function expressions.
- Wait for the state the function depends on.
When it happens
Trigger: pageFunc throws at runtime (bad selector inside evaluate, undefined reference); args contain non-serializable values; navigation destroys the context mid-call; invalid function expression syntax.
Common situations: Grabbing handles to elements that may not exist yet (querySelector returns null then code dereferences it); passing complex args; evaluating during form-submit navigations.
Related errors
- evaluating JS: %w
- evaluating handle for frame: execution context %q not found
- dispatching element event %q: %w
- getting injected script: %w
- converting argument %q in execution context ID %d and frame
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/59f9d864aaf8c25c.
Report an issue: GitHub.