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
- Make waits finish before the iteration ends: await every browser promise and size timeout options inside the scenario duration
- Raise the option timeout or reduce the wait scope so the matcher completes
- During intentional teardown, treat this as expected and skip/log it instead of failing the check
- 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
- Await every browser promise before the end of the default function
- Keep option timeouts comfortably below the scenario/iteration budget
- Treat this error as expected during graceful stop and early-return instead of failing checks
- Avoid firing waitFor* matchers you never await
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
- evaluate requires a page function
- evaluate requires a page function
- evaluateHandle requires a page function
- evaluateHandle requires a page function
- evaluating pattern
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)