grafana/k6 · error

checking is in viewport: unexpected type %T

Error message

checking is %q in viewport: unexpected type %T

What it means

Internal invariant error in k6 browser's frame.isInViewport: after the action succeeds, the value returned by the CDP evaluation must be a Go bool; the type assertion v.(bool) failed. It signals an unexpected protocol/serialization result, not a user-input problem.

Solutions

  1. Re-run the test once to rule out a transient CDP glitch
  2. Check for a k6/Chromium version mismatch and align versions (k6 >= the version that shipped your browser module)
  3. Report it as a k6 bug at https://github.com/grafana/k6/issues with the script and k6 version
  4. Work around by checking visibility and bounding box via elementHandle.boundingBox() instead
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const inVp = frame.isInViewPort ? page.$eval(sel, el => { /* bbox ratio check */ return true; }) : false;
} catch (e) {
  console.log(`viewport check failed (likely internal): ${e}`);
}

Prevention

When it happens

Trigger: Calling elementHandle.../page.isInViewPort-style internal path where the in-viewport ratio evaluation returns a non-bool remote value — realistically only from a Chromium/k6 version mismatch or an internal bug, since the evaluated JS always produces a boolean.

Common situations: Upgrading k6 or the bundled Chromium to mismatched versions; virtually never seen in normal test runs because the injected script returns a boolean by construction.

Related errors


AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18). Data as JSON: /api/errors/bbdc3af23c473c19. Report an issue: GitHub.

Appendix: source

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

func (f *Frame) isInViewport(selector string, opts *FrameIsInViewportOptions) (bool, error) {
	isInViewport := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
		v, err := handle.isInViewport(apiCtx, opts.Ratio)
		if errors.Is(err, ErrTimedOut) { // We don't care about timeout errors here!
			return v, nil
		}
		return v, err
	}
	act := f.newAction(
		selector, DOMElementStateAttached, opts.Strict, isInViewport, []string{}, false, withRetry, true, opts.Timeout,
	)
	v, err := call(f.ctx, act, opts.Timeout)
	if err != nil {
		return false, errorFromDOMError(err)
	}

	bv, ok := v.(bool)
	if !ok {
		return false, fmt.Errorf("checking is %q in viewport: unexpected type %T", selector, v)
	}

	return bv, nil
}

// ID returns the frame id.
func (f *Frame) ID() string {
	f.propertiesMu.RLock()
	defer f.propertiesMu.RUnlock()

	return f.id.String()
}

// Locator creates and returns a new locator for this frame.
func (f *Frame) Locator(selector string, opts *LocatorOptions) *Locator {
	f.log.Debugf("Frame:Locator", "fid:%s furl:%q selector:%q opts:%+v", f.ID(), f.URL(), selector, opts)

	return NewLocator(f.ctx, opts, selector, f, f.log)

View on GitHub (pinned to 3fcf5388d7)