grafana/k6 · error

filling %q with %q: %w

Error message

filling %q with %q: %w

What it means

Frame.Fill() runs an action that waits for the element to be actionable and then sets its value directly (with an input event). This error wraps the underlying failures: 'element is not an <input>, <textarea> or [contenteditable]' from the injected script, 'element is not editable' (readonly/disabled), or a wait timeout.

Source

Thrown at internal/js/modules/k6/browser/common/frame.go:932

	}

	f.waitForExecutionContext(mainWorld)
	handle, err := evalHandle()
	if err != nil {
		return nil, fmt.Errorf("evaluating handle for frame: %w", err)
	}

	applySlowMo(f.ctx)

	return handle, nil
}

// Fill fills out the first element found that matches the selector.
func (f *Frame) Fill(selector, value string, popts *FrameFillOptions) error {
	f.log.Debugf("Frame:Fill", "fid:%s furl:%q sel:%q val:%q", f.ID(), f.URL(), selector, value)

	if err := f.fill(selector, value, popts); err != nil {
		return fmt.Errorf("filling %q with %q: %w", selector, value, err)
	}

	applySlowMo(f.ctx)

	return nil
}

func (f *Frame) fill(selector, value string, opts *FrameFillOptions) error {
	fill := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
		return nil, handle.fill(apiCtx, value)
	}
	act := f.newAction(
		selector, DOMElementStateAttached, opts.Strict,
		fill, []string{"visible", "enabled", "editable"},
		opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
	)
	if _, err := call(f.ctx, act, opts.Timeout); err != nil {
		return errorFromDOMError(err)

View on GitHub (pinned to 93accf6570)

Solutions

  1. Confirm the target is input/textarea/contenteditable; for selects use frame.selectOption(), for custom widgets use click()/type().
  2. Use a unique selector and waitForSelector visible before filling.
  3. Remove readonly/disabled or pick a different field if the app blocks direct edits.

Example fix

// before
frame.fill('.date-display', '2026-08-15'); // div -> not an input

// after
frame.click('.date-display');
frame.type('.date-display input', '2026-08-15');
Defensive patterns

Strategy: validation

Validate before calling

await frame.waitForSelector(sel, { state: 'visible', timeout: 30000 });
const fillable = await frame.evaluate(
  '(s) => { const el = document.querySelector(s); return !!el && (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.isContentEditable) && !el.disabled && !el.readOnly; }',
  sel
);

Try / catch

try {
  frame.fill(sel, value, { timeout: 30000 });
} catch (e) {
  if (/not an <input>|not editable/.test(e.message)) { /* wrong element kind — use click/type or selectOption */ }
}

Prevention

When it happens

Trigger: Filling a selector that points to a non-input element (div, span, custom widget); target is readonly/disabled; element hidden/covered so actionability checks time out; strict-mode multiple matches.

Common situations: Custom dropdowns/date pickers that are not real inputs (need click-based interaction); readonly form fields; select elements (fill does not apply — use selectOption); late-rendered inputs in SPAs.

Related errors


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