grafana/k6 · warning

value out of range for int32 type

Error message

value %v out of range for int32 type

What it means

In ElementHandle's count() path, the injected script returned a numeric element count that falls outside the int32 range before being cast to int. Mathematically this cannot happen for a real DOM query result, so hitting it implies a corrupted evaluation result rather than an actual page with billions of elements.

Solutions

  1. Re-run the count on a plain page to check for evaluation corruption
  2. Upgrade k6 in case of an internal counting regression
  3. Replace el.count() with an evaluate-based count as a workaround
  4. Report to k6 with the reproducer if persistent

Example fix

// workaround
// before
const n = await page.locator('.item').count();

// after
const n = await page.evaluate(() => document.querySelectorAll('.item').length);
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const n = await page.locator('.item').count();
} catch (e) {
  if (/out of range for int32/.test(String(e))) {
    const n = await page.evaluate(() => document.querySelectorAll('.item').length);
  } else throw e;
}

Prevention

When it happens

Trigger: el.count() / internal count queries (including the frame-chained count path above it) where the JS evaluation returns Infinity, NaN-like large values, or garbage due to page tampering or a broken eval; the float64 range check at element_handle.go:762 rejects it.

Common situations: Practically never in real usage; if reported it accompanies a broken evaluation environment (page overriding the injected helpers) or an internal k6 bug.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

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

			(node, injected, selector) => {
				return injected.count(selector, node);
			}
		`
	eopts := evalOptions{
		forceCallable: true,
		returnByValue: true,
	}
	result, err := h.evalWithScript(
		apiCtx,
		eopts, fn, parsedSelector,
	)
	if err != nil {
		return 0, err
	}
	switch r := result.(type) {
	case float64:
		if r < float64(math.MinInt32) || r > float64(math.MaxInt32) {
			return 0, fmt.Errorf("value %v out of range for int32 type", r)
		}
		return int(r), nil
	default:
		return 0, fmt.Errorf("unexpected value %v of type %T", r, r)
	}
}

// findFrameNavigationIndex finds the index of the first internal:control=enter-frame directive
func (h *ElementHandle) findFrameNavigationIndex(selector *Selector) int {
	for i, part := range selector.Parts {
		if part.Name == "internal:control" && part.Body == "enter-frame" {
			return i
		}
	}
	return -1
}

// splitSelectorAtFrame splits a selector at the frame navigation boundary

View on GitHub (pinned to 3fcf5388d7)