grafana/k6 · error

steps must be an integer, got

Error message

steps must be an integer, got %s

What it means

Thrown by the k6 browser module when parsing the options object of page.mouse.move(x, y, opts). The parser (parseMouseMoveOptions in internal/js/modules/k6/browser/browser/mouse_mapping.go:150-170) requires the 'steps' key to export as a Go int64; any other reflect.Kind (float64, string, bool, object) is rejected with the actual kind name in the message. It is a synchronous argument-validation error: the CDP mouse event is never sent.

Solutions

  1. Pass an integer literal or a pre-rounded value: page.mouse.move(x, y, { steps: 5 }) or { steps: Math.max(1, Math.round(delta)) }
  2. If the value comes from configuration, convert it first: const steps = Number.parseInt(rawSteps, 10) and check Number.isInteger(steps) before the call
  3. Verify the rendered options object (console.log or k6 debug log) to confirm no string or fractional value leaks into steps

Example fix

// before
const steps = __ENV.MOVE_STEPS;            // string like "5"
await page.mouse.move(0, 100, { steps });     // steps must be an integer, got string

// after
const steps = Number.parseInt(__ENV.MOVE_STEPS, 10);
if (!Number.isInteger(steps) || steps < 1) throw new Error('MOVE_STEPS must be a positive integer');
await page.mouse.move(0, 100, { steps });
Defensive patterns

Strategy: validation

Validate before calling

const steps = Number.parseInt(rawSteps, 10);
if (!Number.isInteger(steps) || steps < 1) {
  throw new Error(`steps must be a positive integer, got: ${rawSteps}`);
}
await page.mouse.move(x, y, { steps });

Type guard

/** @param {unknown} v */
function isValidSteps(v) {
  return typeof v === 'number' && Number.isInteger(v) && v >= 1;
}

Try / catch

try {
  await page.mouse.move(x, y, { steps });
} catch (e) {
  if (String(e).includes('steps must be an integer')) {
    console.warn(`invalid steps value: ${steps}; using default`);
    await page.mouse.move(x, y);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling page.mouse.move(100, 200, { steps: 2.5 }) (non-integral number exports as float64); steps passed as a string such as { steps: '5' } (common when the value comes from an env var or JSON config); steps as a boolean or object; computed values like steps: distance/10 where the division yields a fraction.

Common situations: Test data loaded from JSON/environment variables where all values are strings; porting Playwright scripts that compute steps dynamically; dividing pixel distances and forgetting to round; note that plain integer literals (steps: 5) export as int64 and work fine.

Related errors


AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18). Data as JSON: /api/errors/119a50508a421400. Report an issue: GitHub.

Appendix: source

Thrown at internal/js/modules/k6/browser/browser/mouse_mapping.go:164

	return popts, nil
}

// parseMouseMoveOptions parses the mouse move options from a Sobek value.
func parseMouseMoveOptions(rt *sobek.Runtime, opts sobek.Value) (*common.MouseMoveOptions, error) {
	popts := common.NewMouseMoveOptions()
	if k6common.IsNullish(opts) {
		return popts, nil
	}

	obj := opts.ToObject(rt)
	for _, k := range obj.Keys() {
		if k == "steps" {
			v := obj.Get(k)
			switch v.ExportType().Kind() {
			case reflect.Int64:
				popts.Steps = v.ToInteger()
			default:
				return nil, fmt.Errorf("steps must be an integer, got %s", v.ExportType().Kind())
			}
		}
	}

	return popts, nil
}

View on GitHub (pinned to 01ffac6f24)