grafana/k6 · error
fail to abort request (id: %s): %w
Error message
fail to abort request (id: %s): %w
What it means
The CDP command Fetch.failRequest returned an error while trying to abort a request, and the error was not context.Canceled (which is deliberately swallowed as debug noise). The interception could not be delivered — usually because the request/target no longer exists on the browser side.
Source
Thrown at internal/js/modules/k6/browser/common/network_manager.go:925
}
func (m *NetworkManager) AbortRequest(requestID fetch.RequestID, errorReason string) error {
m.logger.Debugf("NetworkManager:AbortRequest", "aborting request (id: %s, errorReason: %s)",
requestID, errorReason)
netErrorReason, ok := m.errorReasons[errorReason]
if !ok {
return fmt.Errorf("unknown error code: %s", errorReason)
}
action := fetch.FailRequest(requestID, netErrorReason)
if err := action.Do(cdp.WithExecutor(m.ctx, m.session)); err != nil {
// Avoid logging as error when context is canceled.
// Most probably this happens when trying to fail a site's background request
// while the iteration is ending and therefore the browser context is being closed.
if errors.Is(err, context.Canceled) {
m.logger.Debug("NetworkManager:AbortRequest", "context canceled interrupting request")
} else {
return fmt.Errorf("fail to abort request (id: %s): %w", requestID, err)
}
}
return nil
}
func (m *NetworkManager) ContinueRequest(
requestID fetch.RequestID,
opts ContinueOptions,
originalHeaders []HTTPHeader,
) error {
m.logger.Debugf("NetworkManager:ContinueRequest", "continuing request (id: %s)", requestID)
action := fetch.ContinueRequest(requestID)
if len(opts.Headers) > 0 {
action = action.WithHeaders(toFetchHeaders(opts.Headers))
}
if opts.URL != "" {View on GitHub (pinned to 93accf6570)
Solutions
- Abort early in the handler — before any await that can let navigation proceed
- Only handle each intercepted request once (abort XOR continue XOR fulfill)
- If it only occurs at iteration end, it is teardown noise: stop aborting once the iteration is ending, or catch and ignore at the script level if acceptable for your assertions
- Reduce the race by unroute()-ing before page.close()
Example fix
// before
page.route('**/*', async r => {
await somethingSlow();
await r.abort('aborted'); // request may be gone by now
});
// after
page.route('**/*', r => r.abort('aborted')); // decide and abort immediately Defensive patterns
Strategy: try-catch
Validate before calling
if (page.isClosed()) { /* skip aborting: request lifecycle already over */ } Try / catch
try {
await route.abort('aborted');
} catch (e) {
if (/fail to abort request/.test(String(e))) return; // stale request; nothing to abort
throw e;
} Prevention
- Abort immediately and synchronously in the handler — no awaits before the decision
- Unroute before closing the page so pending handler work drains in order
- Don't abort the same route twice
When it happens
Trigger: route.abort(reason) executed after the page navigated away or the target was destroyed, so the fetch.RequestID is stale; aborting a background request (analytics, long-poll, service worker fetch) while the browser context is closing but the context wasn't canceled yet; double-handling the same route (abort twice).
Common situations: Aborting third-party/background requests at end-of-iteration; handlers racing page.close(); SPA sites that re-issue requests during navigation so the handler's request is already gone.
Related errors
- fail to continue request (id: %s): %w
- fail to fulfill request (id: %s): %w
- parent frame has been detached
- attaching new page: %w
- getting node in frame: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/3799a2da74e41148.
Report an issue: GitHub.