grafana/k6 · error
retrieving json value: %w
Error message
retrieving json value: %w
What it means
Thrown by BaseJSHandle.JSONValue when the CDP Runtime.callFunctionOn('function() { return this; }') round-trip fails for an object-backed handle. The handle's remote object ID is no longer resolvable by the browser (released, GC'd, or its context destroyed), so the protocol call itself errors before any JSON parsing happens.
Source
Thrown at internal/js/modules/k6/browser/common/js_handle.go:202
continue
}
props[r.Name] = NewJSHandle(h.ctx, h.session, h.execCtx, h.execCtx.Frame(), r.Value, h.logger)
}
return props, nil
}
// JSONValue returns a JSON version of this JS handle.
func (h *BaseJSHandle) JSONValue() (string, error) {
remoteObject := h.remoteObject
if remoteObject.ObjectID != "" {
var err error
action := runtime.CallFunctionOn("function() { return this; }").
WithReturnByValue(true).
WithAwaitPromise(true).
WithObjectID(h.remoteObject.ObjectID)
if remoteObject, _, err = action.Do(cdp.WithExecutor(h.ctx, h.session)); err != nil {
return "", fmt.Errorf("retrieving json value: %w", err)
}
}
res, err := parseConsoleRemoteObject(h.logger, remoteObject)
if err != nil {
return "", fmt.Errorf("extracting json value (remote object id: %v): %w", remoteObject.ObjectID, err)
}
return res, nil
}
// ObjectID returns the remote object ID.
func (h *BaseJSHandle) ObjectID() runtime.RemoteObjectID {
return h.remoteObject.ObjectID
}
View on GitHub (pinned to 93accf6570)
Solutions
- Call jsonValue() immediately after obtaining the handle, before any navigation
- Re-query the element and retry once if the handle has gone stale
- Do not call dispose() before extracting values
- Prefer locator.textContent()/innerText() style helpers which re-resolve the element per call
Example fix
// before
const h = await page.$('h1');
await page.goto('https://example.com/next'); // invalidates handle
const text = await h.jsonValue();
// after
await page.goto('https://example.com/next');
const h = await page.$('h1');
const text = await h.jsonValue(); Defensive patterns
Strategy: try-catch
Validate before calling
if (page.isClosed()) throw new Error('page closed before jsonValue'); Try / catch
try {
return await handle.jsonValue();
} catch (e) {
if (/retrieving json value/.test(e.message)) {
const fresh = await page.$(selector);
return fresh.jsonValue(); // stale remote object: re-acquire once
}
throw e;
} Prevention
- Extract values immediately after obtaining the handle
- Prefer element accessors (textContent(), getAttribute()) over jsonValue() on elements
- Do not dispose handles before reading their values
When it happens
Trigger: Calling jsonValue() on a handle whose object was garbage-collected by the browser; using a handle after navigation destroyed its execution context; calling jsonValue() after dispose(); page or session closed during the call.
Common situations: Extracting text or attributes via handle.jsonValue() from handles kept alive across multiple page transitions; long test iterations where VU-level timeouts cancel the session mid-call.
Related errors
- getting properties for element with ID %s: %w
- extracting value from remote object with ID %s: %w
- disposing element with ID %s: %w
- evaluating element: %w
- evaluating handle for element: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/2118333ecfacca0c.
Report an issue: GitHub.