grafana/k6 · error

checking element is in viewport: unexpected type %T

Error message

checking element is in viewport: unexpected type %T

What it means

Returned by ElementHandle's in-viewport verification: the injected script that checks whether the element intersects the viewport (with the given ratio) returned neither a bool nor a string status. It is an internal type-contract violation; normal outcomes are a bool (is/isn't in viewport) or an 'error:...' string.

Solutions

  1. Upgrade k6 to rule out internal regression
  2. Confirm behavior on a static page to rule out app-side script interference
  3. Avoid forcing viewport checks (el.scrollIntoViewIfNeeded already handles scrolling); if it keeps failing, scroll manually via el.evaluate
  4. Report to k6 with a minimal reproducer
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await el.scrollIntoViewIfNeeded();
} catch (e) {
  if (/in viewport/.test(String(e))) {
    await el.evaluate((node) => node.scrollIntoView({ block: 'center' }));
  } else throw e;
}

Prevention

When it happens

Trigger: Viewport checks performed as part of scrollIntoViewIfNeeded/actionability where the injected script's return value comes back as an unexpected type (object/number/undefined) due to page-side tampering or an internal regression; passing a non-numeric ratio from the API surface would surface earlier as an eval error.

Common situations: Pages overriding prototypes that the injected script relies on; version skew in k6 internals; not triggered by ordinary CSS/layout conditions — genuine 'not in viewport' cases return false, not this error.

Related errors


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

Appendix: source

Thrown at internal/js/modules/k6/browser/common/element_handle.go:417

			return injected.isInViewport(node, ratio);
		}
	`
	opts := evalOptions{
		forceCallable: true,
		returnByValue: true,
	}
	result, err := h.evalWithScript(apiCtx, opts, fn, ratio)
	if err != nil {
		return false, errorFromDOMError(err)
	}
	switch v := result.(type) {
	case string: // An error happened (returned as "error:..." from JS)
		return false, errorFromDOMError(v)
	case bool:
		return v, nil
	}

	return false, fmt.Errorf(
		"checking element is in viewport: unexpected type %T", result)
}

func (h *ElementHandle) offsetPosition(apiCtx context.Context, offset *Position) (*Position, error) {
	fn := `
		(node, injected) => {
			return injected.getElementBorderWidth(node);
		}
	`
	opts := evalOptions{
		forceCallable: true,
		returnByValue: true,
	}
	result, err := h.evalWithScript(apiCtx, opts, fn)
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 3fcf5388d7)