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

  1. Call jsonValue() immediately after obtaining the handle, before any navigation
  2. Re-query the element and retry once if the handle has gone stale
  3. Do not call dispose() before extracting values
  4. 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

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


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/2118333ecfacca0c. Report an issue: GitHub.