grafana/k6 · error

getting attribute %q of element: unexpected type %T (expecti

Error message

getting attribute %q of element: unexpected type %T (expecting string)

What it means

Internal invariant failure inside ElementHandle.getAttribute(name): the CDP evaluation succeeded but the returned remote value did not type-assert to a Go string. DOM attribute values are strings by spec (or null, which is handled earlier), so a non-string payload means an unexpected protocol serialization or a k6 bug, not a normal scripting mistake.

Source

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

func (h *ElementHandle) GetAttribute(name string) (string, bool, error) {
	getAttribute := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
		return handle.getAttribute(apiCtx, name)
	}
	opts := NewElementHandleBaseOptions(h.DefaultTimeout())
	getAttributeAction := h.newAction(
		[]string{}, getAttribute, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
	)

	v, err := call(h.ctx, getAttributeAction, opts.Timeout)
	if err != nil {
		return "", false, fmt.Errorf("getting attribute %q of element: %w", name, err)
	}
	if v == nil {
		return "", false, nil
	}
	s, ok := v.(string)
	if !ok {
		return "", false, fmt.Errorf(
			"getting attribute %q of element: unexpected type %T (expecting string)",
			name, v,
		)
	}

	return s, true, nil
}

// Hover scrolls element into view and hovers over its center point.
func (h *ElementHandle) Hover(opts *ElementHandleHoverOptions) error {
	hover := func(apiCtx context.Context, handle *ElementHandle, p *Position) (any, error) {
		return nil, handle.hover(apiCtx, p)
	}
	hoverAction := h.newPointerAction(hover, &opts.ElementHandleBasePointerOptions)
	if _, err := call(h.ctx, hoverAction, opts.Timeout); err != nil {
		return fmt.Errorf("hovering on element: %w", err)
	}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Upgrade k6 to the latest release - the browser module tracks Chromium versions closely
  2. Pin the browser binary to a version known to work with your k6 release
  3. Work around it by reading the attribute through evaluate: page.evaluate(el => el.getAttribute(name), handle)
  4. Report the issue to k6 with the script, k6 version, and Chromium version

Example fix

// before
const [v, ok] = await h.getAttribute('data-id');
// after (workaround via evaluate)
const v = await h.evaluate((el) => el.getAttribute('data-id'));
if (typeof v !== 'string') { /* treat as missing */ }
Defensive patterns

Strategy: validation

Validate before calling

const v = await handle.evaluate((el, name) => el.getAttribute(name), name);
if (typeof v === 'string') {
  // safe to use
}

Type guard

function isAttrString(v) {
  return typeof v === 'string';
}

Try / catch

try {
  const [v, ok] = await handle.getAttribute(name);
} catch (e) {
  if (String(e).includes('unexpected type')) {
    return handle.evaluate((el) => el.getAttribute(name), name);
  }
  throw e;
}

Prevention

When it happens

Trigger: Only produced when the browser returns a non-string RemoteObject for the attribute evaluation - typically a Chromium/CDP version mismatch with the k6 release, or a regression in the injected evaluation. Not reproducible through ordinary script inputs.

Common situations: Running a much newer or canary Chromium against an older k6; custom browser binaries via K6_BROWSER_EXECUTABLE_PATH; after a k6 upgrade changed the evaluation plumbing.

Related errors


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