grafana/k6 · warning

running on task queue

Error message

running on task queue: %w

What it means

Returned by queueTask (browser/helpers.go:129) when the VU context finishes (Canceled or DeadlineExceeded, surfaced via common.ContextErr) before a queued task ran. In the browser mapping this guards the event-loop task queue used by the regex matcher behind waitForURL, waitForNavigation({ url }), waitForRequest, waitForResponse and route, so the error means 'the iteration/test was torn down while pattern matching was still pending', not a pattern problem.

Solutions

  1. Make waits finish before the iteration ends: await every browser promise and size timeout options inside the scenario duration
  2. Raise the option timeout or reduce the wait scope so the matcher completes
  3. During intentional teardown, treat this as expected and skip/log it instead of failing the check
  4. Upgrade k6 — the browser module's iteration-close behavior has been stabilized over releases

Example fix

// before
const p = page.waitForNavigation({ url: /\/next/ }); // not awaited, iteration ends
// after
const p = page.waitForNavigation({ url: /\/next/, timeout: 5000 });
await p; // completes within the iteration budget
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const nav = page.waitForNavigation({ url: /\/next\/, timeout: 5000 });
  await page.click('#go');
  await nav;
} catch (e) {
  if (!String(e.message).includes('running on task queue')) throw e;
  // iteration is being torn down; skip remaining browser work
}

Prevention

When it happens

Trigger: The VU iteration ends (scenario duration/graceful stop, SIGINT abort, or an iteration timeout) while a URL-pattern wait is still pending; closing the browser context/page with a waitForNavigation-style matcher in flight; end-of-test teardown racing the task queue.

Common situations: Short scenarios where waitForURL/waitForResponse outlive the iteration budget; k6 graceful-stop at end-of-test producing a burst of these; over-tight iterationTimeout or per-iteration budgets in arrival-rate executors.

Related errors


AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18). Data as JSON: /api/errors/b5f94d5cb28eae14. Report an issue: GitHub.

Appendix: source

Thrown at internal/js/modules/k6/browser/browser/helpers.go:129

	fn func() (T, error),
) (future func() (T, error)) {
	var (
		result T
		err    error
		done   = make(chan struct{})
	)
	tq.Queue(func() error {
		defer close(done)
		result, err = fn()
		return err
	})
	return func() (T, error) {
		select {
		case <-done:
			return result, err
		case <-ctx.Done():
			var zero T
			return zero, fmt.Errorf("running on task queue: %w", common.ContextErr(ctx))
		}
	}
}

// newTaskQueue returns a new [taskqueue.TaskQueue] that is closed after
// the returned cancel function is called or when the VU's context is done.
//
// Do not call this function off of the event loop.
func newTaskQueue(vu moduleVU) (*taskqueue.TaskQueue, context.Context, context.CancelFunc) {
	ctx, cancel := context.WithCancel(vu.Context())
	tq := taskqueue.New(vu.RegisterCallback)
	go func() {
		<-ctx.Done()
		tq.Close()
	}()
	return tq, ctx, cancel
}

View on GitHub (pinned to 01ffac6f24)