grafana/k6 · error

%w

Error message

%w

What it means

Returned by the internal wait() helper used for keyboard Delay options: the context was canceled (or its deadline exceeded) while sleeping between keystrokes, so ContextErr(ctx) — context.Canceled / context.DeadlineExceeded, with any cancel cause appended — is passed through unchanged (fmt.Errorf("%w", ...)). It aborts Type/Press waits before the next key is sent.

Source

Thrown at internal/js/modules/k6/browser/common/keyboard.go:347

				return fmt.Errorf("pressing key: %w", err)
			}
			continue
		}
		if err := k.insertText(string(c)); err != nil {
			return fmt.Errorf("inserting text: %w", err)
		}
	}
	return nil
}

func wait(ctx context.Context, delay int64) error {
	t := time.NewTimer(time.Duration(delay) * time.Millisecond)
	select {
	case <-ctx.Done():
		if !t.Stop() {
			<-t.C
		}
		return fmt.Errorf("%w", ContextErr(ctx))
	case <-t.C:
	}

	return nil
}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Budget delays: total ≈ len(text) * delay must stay well under the timeout option and iteration duration
  2. Use insertText() for long strings when no per-key events are needed
  3. Raise the timeout option (browser option) or shorten per-char delay
  4. Treat context.Canceled at teardown as expected: end typing before closing pages

Example fix

// before
await page.type('#bio', longText, { delay: 200 }); // 200ms * 500 chars = 100s > timeout

// after
await page.keyboard.insertText(longText);         // no delays
// or: await page.type('#bio', longText, { delay: 5 });
Defensive patterns

Strategy: validation

Validate before calling

const totalWaitMs = chars * delayMs; // cumulative wait() sleeps before each key
if (totalWaitMs > actionTimeoutMs * 0.8 || totalWaitMs > remainingIterationMs) {
  throw new Error('typing delay budget exceeds timeout — lower delay or use insertText()');
}

Try / catch

try {
  await page.keyboard.type(text, { delay });
} catch (e) {
  if (/context deadline exceeded|context canceled/.test(e.message)) {
    console.warn('typing aborted by timeout/cancel during delay — finishing with insertText');
    await page.keyboard.insertText(text); // best-effort completion without delays
  } else throw e;
}

Prevention

When it happens

Trigger: type(text, {delay: 500}) where the cumulative delay exceeds the k6 iteration timeout or browser timeout; press(key, {delay: N}) where the page/browser context closes during the delay; scenario teardown canceling ctx mid-wait.

Common situations: Realistic-human typing delays (50–200ms per char) on long strings colliding with tight timeout options; end-of-iteration cancellation while a Type call is still sleeping; ctx canceled by page.close() with a pending delayed key.

Related errors


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