grafana/k6 · error

filling element

Error message

filling element: %w

What it means

ElementHandle.fill() runs with 'visible', 'enabled' and 'editable' actionability preconditions, then an injected script focuses the node and sets its value. The wrapped error can be an actionability timeout, a DOM-level error returned by the injected script (e.g. 'Node is not editable'), or a stale/detached handle failure.

Solutions

  1. Target the real input/textarea/contenteditable element inside the component instead of its wrapper
  2. If the field is readonly by design, use el.type() or el.press() instead of fill()
  3. Wait for editability first: await el.waitFor({ state: 'visible' }) and check await el.isEditable()
  4. Increase the timeout: await el.fill('text', { timeout: '60s' })
  5. Use { force: true } only to skip actionability waits - it will not bypass a genuine non-editable error

Example fix

// before
const el = await page.$('.my-combobox');
await el.fill('k6'); // wrapper div is not editable

// after
const el = await page.$('.my-combobox input');
if (!(await el.isEditable())) throw new Error('combobox input not editable yet');
await el.fill('k6');
Defensive patterns

Strategy: validation

Validate before calling

// Validate the target is an editable field before filling
const editable = await el.isEditable(); // ignores timeouts by design
if (!editable) {
  throw new Error('target is not editable; select a real input/textarea');
}
await el.fill('k6');

Try / catch

try {
  await el.fill('k6');
} catch (e) {
  const msg = String(e.message);
  if (/not editable|readonly/i.test(msg)) {
    await el.click();
    await el.type('k6'); // fallback for readonly-by-design fields
  } else if (/timed out/i.test(msg)) {
    await el.fill('k6', { timeout: '60s' });
  } else throw e;
}

Prevention

When it happens

Trigger: The target is not a real input (div, span, or a component wrapper without an input inside); the input is readonly or disabled; the element is a contenteditable=false node; the actionability wait for visible/enabled/editable times out; the element was re-rendered between query and fill.

Common situations: Custom dropdown/autocomplete components that are not native inputs; form fields only enabled after async validation completes; readonly fields designed to be set via keyboard events; shadow-DOM components where the handle resolves to the host element instead of the inner input.

Related errors


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

Appendix: source

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

		return fmt.Errorf("dispatching element event %q: %w", typ, err)
	}

	applySlowMo(h.ctx)

	return nil
}

// Fill types the given value into the element.
func (h *ElementHandle) Fill(value string, opts *ElementHandleBaseOptions) error {
	fill := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
		return nil, handle.fill(apiCtx, value)
	}
	fillAction := h.newAction(
		[]string{"visible", "enabled", "editable"},
		fill, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
	)
	if _, err := call(h.ctx, fillAction, opts.Timeout); err != nil {
		return fmt.Errorf("filling element: %w", err)
	}

	applySlowMo(h.ctx)

	return nil
}

// Focus scrolls element into view and focuses the element.
func (h *ElementHandle) Focus() error {
	focus := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
		return nil, handle.focus(apiCtx, false)
	}
	opts := NewElementHandleBaseOptions(h.DefaultTimeout())
	focusAction := h.newAction(
		[]string{}, focus, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
	)
	if _, err := call(h.ctx, focusAction, opts.Timeout); err != nil {
		return fmt.Errorf("focusing on element: %w", err)

View on GitHub (pinned to 3fcf5388d7)