grafana/k6 · error
evaluating element: %w
Error message
evaluating element: %w
What it means
BaseJSHandle.Evaluate prepends the handle itself as the first argument and runs your page function in the handle's execution context via execCtx.Eval. This error wraps any failure from that evaluation: a JavaScript exception thrown inside the function, the execution context having been destroyed by navigation, an argument conversion failure, or a session problem.
Source
Thrown at internal/js/modules/k6/browser/common/js_handle.go:140
h.disposed = true
if h.remoteObject.ObjectID == "" {
return nil
}
act := runtime.ReleaseObject(h.remoteObject.ObjectID)
if err := act.Do(cdp.WithExecutor(h.ctx, h.session)); err != nil {
return fmt.Errorf("disposing element with ID %s: %w",
h.remoteObject.ObjectID, err)
}
return nil
}
// Evaluate will evaluate provided page function within an execution context.
func (h *BaseJSHandle) Evaluate(pageFunc string, args ...any) (any, error) {
args = append([]any{h}, args...)
res, err := h.execCtx.Eval(h.ctx, pageFunc, args...)
if err != nil {
return nil, fmt.Errorf("evaluating element: %w", err)
}
return res, nil
}
// EvaluateHandle will evaluate provided page function within an execution context.
func (h *BaseJSHandle) EvaluateHandle(pageFunc string, args ...any) (JSHandleAPI, error) {
args = append([]any{h}, args...)
eh, err := h.execCtx.EvalHandle(h.ctx, pageFunc, args...)
if err != nil {
return nil, fmt.Errorf("evaluating handle for element: %w", err)
}
return eh, nil
}
// GetProperties retreives the JS handle's properties.
func (h *BaseJSHandle) GetProperties() (map[string]JSHandleAPI, error) {View on GitHub (pinned to 93accf6570)
Solutions
- Re-query the element right before evaluate instead of reusing stale handles
- Make the evaluated function defensive (optional chaining, null checks) so it does not throw on missing nodes
- Wait for a stable state (page.waitForLoadState, waitForSelector) before evaluating
- Retry once with a freshly queried handle if the failure was caused by navigation
Example fix
// before
const btn = await page.$('#submit');
await page.goto(url2);
await btn.evaluate((b) => b.textContent.length); // context destroyed
// after
await page.goto(url2);
const btn = await page.$('#submit');
await btn.evaluate((b) => b?.textContent?.length ?? 0); Defensive patterns
Strategy: try-catch
Validate before calling
// re-query right before evaluating, and prefer locator-style flows
const btn = await page.$('#submit');
const label = await btn.evaluate((b) => b?.textContent ?? ''); Try / catch
try {
result = await handle.evaluate(fn);
} catch (e) {
if (!/evaluating element/.test(String(e.message))) throw e;
const fresh = await page.$(selector); // re-query after navigation
result = await fresh.evaluate(fn);
} Prevention
- Re-query element handles after any navigation instead of reusing them
- Write defensive page functions (optional chaining, null defaults)
- Wait for load/selector stability before evaluating on handles
When it happens
Trigger: handle.evaluate(fn) where fn throws at runtime (property access on a stale/detached element, null returned from a lookup), where the handle's execution context was destroyed by navigation or iframe replacement, or where arguments fail conversion before the call.
Common situations: Reusing element handles after page navigation or DOM re-renders (classic stale-handle problem); evaluating on elements inside frames that reloaded; functions that assume a property exists; evaluate racing a route-fulfilled navigation.
Related errors
- evaluating JS: %w
- evaluating JS in global context: %w
- getting properties for element with ID %s: %w
- retrieving json value: %w
- evaluate requires a page function
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/4e0c6ad3c2ac8199.
Report an issue: GitHub.