grafana/k6 · error

evaluating handle of %q: unexpected type %T

Error message

evaluating handle of %q: unexpected type %T

What it means

Internal invariant violation in Frame.evaluateWithSelector's action pipeline: the action completed without error but its result could not be type-asserted to JSHandleAPI. evaluateHandle is supposed to wrap every CDP eval result in a handle, so reaching this branch means k6's own wrapping layer returned an unexpected Go type — effectively an internal k6 bug, not a user input error.

Source

Thrown at internal/js/modules/k6/browser/common/frame.go:2314

func (f *Frame) evaluateHandleWithSelector(selector string, pageFunc string, args ...any) (JSHandleAPI, error) {
	f.log.Debugf("Frame:evaluateHandleWithSelector", "fid:%s furl:%q sel:%q", f.ID(), f.URL(), selector)

	evaluateHandle := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
		return handle.EvaluateHandle(pageFunc, args...)
	}

	act := f.newAction(
		selector, DOMElementStateAttached, true, evaluateHandle, []string{}, false, withRetry, true, f.defaultTimeout(),
	)
	v, err := call(f.ctx, act, f.defaultTimeout())
	if err != nil {
		return nil, errorFromDOMError(err)
	}

	handle, ok := v.(JSHandleAPI)
	if !ok {
		return nil, fmt.Errorf("evaluating handle of %q: unexpected type %T", selector, v)
	}

	return handle, nil
}

// frameExecutionContext represents a JS execution context that belongs to Frame.
type frameExecutionContext interface {
	// adoptBackendNodeID adopts specified backend node into this execution
	// context from another execution context.
	adoptBackendNodeID(backendNodeID cdp.BackendNodeID) (*ElementHandle, error)

	// adoptElementHandle adopts the specified element handle into this
	// execution context from another execution context.
	adoptElementHandle(elementHandle *ElementHandle) (*ElementHandle, error)

	// eval evaluates the provided JavaScript within this execution context and
	// returns a value or handle.
	eval(

View on GitHub (pinned to 93accf6570)

Solutions

  1. Upgrade k6 to the latest minor — check the k6-browser changelog for JSHandle wrapping fixes
  2. Reproduce with a minimal script and --log-output to capture the type shown in the message (%T names the concrete Go type)
  3. If stable, report at github.com/grafana/k6 with the script and the full error including the type name
Defensive patterns

Strategy: try-catch

Type guard

function isInternalTypeAssertion(e) {
  return e instanceof Error && /unexpected type /.test(e.message);
}

Try / catch

try {
  await page.$eval('#x', (el) => el.value);
} catch (e) {
  if (isInternalTypeAssertion(e)) { /* log %T value and report to k6 */ }
  throw e;
}

Prevention

When it happens

Trigger: Calling frame-level $eval/$$eval/evaluateHandle-style APIs (e.g. page.$eval) while the underlying action machinery hits an edge case (nil result boxed as a non-handle, race in the action channel). No specific user input is known to deterministically trigger it.

Common situations: Rare; appears as one-off reports during heavy parallel browser iterations or around navigation races; often alongside other execution-context errors in the same log.

Related errors


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