grafana/k6 · error
%s
Error message
%s
What it means
The JavaScript that k6 evaluated inside the browser threw an exception. CDP returned exceptionDetails and k6 formats them (script, line, exception text) into this error. It is not a k6 failure: it is the page-side script failing — a syntax error in an evaluated string, a runtime error (undefined variable, null dereference), or an API call failing inside the page.
Source
Thrown at internal/js/modules/k6/browser/common/execution_context.go:224
var (
remoteObject *runtime.RemoteObject
exceptionDetails *runtime.ExceptionDetails
err error
)
if remoteObject, exceptionDetails, err = action.Do(cdp.WithExecutor(apiCtx, e.session)); err != nil {
var cdpe *cdproto.Error
if errors.As(err, &cdpe) && cdpe.Code == devToolsServerErrorCode {
// By creating a new error instead of reusing it, we're removing the
// chromium specific error code.
return nil, errors.New(cdpe.Message)
}
e.logger.Debugf("ExecutionContext:eval", "Unexpected DevTools server error: %v", err)
return nil, err
}
if exceptionDetails != nil {
return nil, fmt.Errorf("%s", parseExceptionDetails(exceptionDetails))
}
var res any
if remoteObject == nil {
e.logger.Debugf(
"ExecutionContext:eval",
"sid:%s stid:%s fid:%s ectxid:%d furl:%q remoteObject is nil",
e.sid, e.stid, e.fid, e.id, e.furl)
return res, nil
}
if opts.returnByValue {
res, err = valueFromRemoteObject(apiCtx, remoteObject)
if err != nil {
return nil, fmt.Errorf(
"extracting value from remote object with ID %s: %w",
remoteObject.ObjectID, err)
}
} else if remoteObject.ObjectID != "" {View on GitHub (pinned to 93accf6570)
Solutions
- Read the message: it contains the page exception text and location
- Guard inside the evaluated script (null checks) or wait for the element first
- Quote strings carefully when passing code as a string; prefer function form
- If the page legitimately throws, catch it inside the evaluated code and return the error instead
Example fix
// before
await page.evaluate('document.querySelector("#x").click()');
// after
await page.click('#x'); // auto-waits for the element, or:
await page.evaluate('const el = document.querySelector("#x"); if (el) el.click();'); Defensive patterns
Strategy: try-catch
Try / catch
try {
await page.evaluate(fn);
} catch (e) {
// e.message carries the page-side exception; decide whether it is expected
if (!/MyExpectedError/.test(e.message)) throw e;
} Prevention
- Wait for elements/state before evaluating code that uses them
- Prefer evaluate with a function over string blobs
- Make page scripts defensive (null checks) when selectors may be absent
- Keep evaluate snippets small so failures are obvious
When it happens
Trigger: page.evaluate('document.querySelector("#missing").click()') where the selector misses (TypeError on null); referencing variables that do not exist in the page context; syntax errors or unbalanced quotes in string-based evaluate calls; expected page errors such as JSON.parse of a failed fetch.
Common situations: Assuming selectors or globals exist without waiting; evaluating code copied from DevTools that depends on page globals; testing failure paths where the page itself throws; evaluating before the page's own scripts initialized.
Related errors
- evaluate requires a page function
- evaluating JS: %w
- k6/experimental/browser has been graduated, please use k6/br
- predicate function is not callable
- parsing new frame check options: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/8b3c4828da649aae.
Report an issue: GitHub.