grafana/k6 · error

fill: %w

Error message

fill: %w

What it means

When the injected fill script returns 'needsinput', k6 completes the fill by calling Keyboard.InsertText (CDP Input.insertText). This error wraps a failure of that CDP input command, so the value could not be typed into the page.

Source

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

			return injected.fill(node, value);
		}
	`
	opts := evalOptions{
		forceCallable: true,
		returnByValue: true,
	}
	result, err := h.evalWithScript(h.ctx, opts, fn, value)
	if err != nil {
		return err
	}
	s, ok := result.(string)
	if !ok {
		return fmt.Errorf("unexpected type %T", result)
	}

	if s == resultNeedsInput {
		if err := h.frame.page.Keyboard.InsertText(value); err != nil {
			return fmt.Errorf("fill: %w", err)
		}
	} else if s != resultDone {
		// Either we're done or an error happened (returned as "error:..." from JS)
		return errorFromDOMError(s)
	}

	return nil
}

func (h *ElementHandle) focus(apiCtx context.Context, resetSelectionIfNotFocused bool) error {
	fn := `
		(node, injected, resetSelectionIfNotFocused) => {
			return injected.focusNode(node, resetSelectionIfNotFocused);
		}
	`
	opts := evalOptions{
		forceCallable: true,
		returnByValue: true,

View on GitHub (pinned to 93accf6570)

Solutions

  1. Retry the fill after re-locating the element and waiting for the page to be idle
  2. Ensure no navigation/submission is triggered between locating the element and filling
  3. Check browser process health and memory limits (headless_shell crashes surface here)
  4. As a workaround for input[type=number] and similar, use click + type() instead of fill()

Example fix

// before
await handle.fill('42'); // fill: Input.insertText failed

// after
await handle.click();
await handle.type('42');
Defensive patterns

Strategy: retry

Validate before calling

// Avoid fills racing navigation
await page.waitForLoadState?.() ?? await page.waitForLoadState();
const el = await page.$(sel);
if (!el) throw new Error('element missing');

Try / catch

async function safeFill(handle, value, tries = 3) {
  for (let i = 0; i < tries; i++) {
    try { return await handle.fill(value); }
    catch (e) {
      if (!String(e).includes('fill:')) throw e;
      await sleep(500);
    }
  }
  throw new Error('fill failed after retries');
}

Prevention

When it happens

Trigger: handle.fill() on elements the script defers to keyboard input while the CDP call fails: page or target closed mid-action, browser session interrupted/crashed, or the element detached between evaluation and text insertion.

Common situations: Page navigation or form submission racing the fill; browser process killed (OOM in constrained CI); flaky headless environments dropping input commands; extremely long fill strings under load.

Related errors


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