grafana/k6 · error
typing text: %w
Error message
typing text: %w
What it means
Wrapper returned by Keyboard.Type when typ() fails. typ() iterates each character: valid layout keys go through press() (down+up with optional per-character delay), everything else falls back to insertText(). The error wraps a canceled wait during Delay, a failed per-character press, or a failed insertText fallback.
Source
Thrown at internal/js/modules/k6/browser/common/keyboard.go:95
return nil
}
// InsertText inserts a text without dispatching key events.
func (k *Keyboard) InsertText(text string) error {
if err := k.insertText(text); err != nil {
return fmt.Errorf("inserting text: %w", err)
}
return nil
}
// Type sends a press message to a session target for each character in text.
// It delays the action if `Delay` option is specified.
//
// It sends an insertText message if a character is not among
// valid characters in the keyboard's layout.
func (k *Keyboard) Type(text string, kbdOpts KeyboardOptions) error {
if err := k.typ(text, kbdOpts); err != nil {
return fmt.Errorf("typing text: %w", err)
}
return nil
}
func (k *Keyboard) down(key string) error {
key = k.platformSpecificResolution(key)
keyInput := keyboardlayout.KeyInput(key)
if _, ok := k.layout.ValidKeys[keyInput]; !ok {
return fmt.Errorf("%q is not a valid key for layout %q", key, k.layoutName)
}
keyDef := k.keyDefinitionFromKey(keyInput)
k.modifiers |= k.modifierBitFromKeyName(keyDef.Key)
text := keyDef.Text
k.pressedKeysMu.Lock()
_, autoRepeat := k.pressedKeys[keyDef.KeyCode]View on GitHub (pinned to 93accf6570)
Solutions
- Compute total time: type() with delay d and n chars blocks ~ n*d ms — keep it well under the timeout option
- For pure text entry without key events, use insertText(text) once instead of per-character typing
- Ensure the page stays open and no navigation occurs while typing
- Catch and retry the full type() from a stable page state (input fields tolerate re-typing after clear())
Example fix
// before
await page.type('#msg', 'a very long status message', { delay: 500 }); // 500ms * ~28 chars
// after
await page.keyboard.insertText('a very long status message'); // no per-char delay Defensive patterns
Strategy: validation
Validate before calling
const totalMs = text.length * (delayMs || 0) + text.length * 5; // heuristic per-char cost
if (totalMs > actionTimeoutMs * 0.8) {
throw new Error('type() duration too close to timeout — lower delay or use insertText()');
}
if (page.isClosed()) throw new Error('page closed before type'); Try / catch
try {
await page.keyboard.type(text, { delay });
} catch (e) {
if (/typing text|pressing key|inserting text|context/.test(e.message)) {
await page.$eval(sel, 'el => el.value = ""');
await page.keyboard.type(text, { delay: 0 }); // retry faster from clean field
} else throw e;
} Prevention
- Budget len(text) * delay against the timeout before typing
- Use insertText() for long or non-ASCII strings
- Ensure no navigation fires while typing (avoid search-as-you-type redirects)
When it happens
Trigger: type('héllo wörld', { delay: 100 }) where 'é'/'ö' take the insertText path and the session dies mid-string; a delay per character times the context out (delay * len > timeout); page closed while typing a long string.
Common situations: Typing long texts with per-character delay exceeding the browser action timeout; typing into a page whose beforeunload/navigation interrupts input; typing after the element was removed so the renderer target changed.
Related errors
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/71ffad568d0f1663.
Report an issue: GitHub.