grafana/k6 · error

%w: %w

Error message

%w: %w

What it means

ContextErr is k6-browser's standard cancellation reporter: it takes ctx.Err() (context.Canceled or context.DeadlineExceeded) and, when the context was cancelled with a cause (context.WithCancelCause), appends that cause as '<ctx error>: <cause>'. So this message is a carrier: the suffix (lost connection, websocket close code, timeout cause) identifies what actually aborted the operation.

Source

Thrown at internal/js/modules/k6/browser/common/context.go:101

		case <-ctx.Done():
		}
	}()
	return ctx
}

// ContextErr returns ctx.Err() and, if present, appends the cancel cause.
func ContextErr(ctx context.Context) error {
	err := ctx.Err()
	if err == nil {
		return nil
	}

	cause := context.Cause(ctx)
	if cause == nil || errors.Is(err, cause) {
		return err
	}

	return fmt.Errorf("%w: %w", err, cause)
}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Read the part after the colon — it names the true cause; fix that (raise timeout, stabilize the browser, await operations).
  2. For deadline-exceeded causes, increase the relevant timeout option (timeouts: { default: '30s' } or K6_BROWSER_TIMEOUT/default settings).
  3. For cancellation at teardown, await pending awaits before the scenario ends.
  4. For connection-loss causes, follow the guidance for errors [643]/[650]/[651].

Example fix

// k6 script: raise browser action timeout
// before
export const options = { browser: { type: 'chromium' } };

// after
export const options = {
  browser: { type: 'chromium' },
  // per-action default used for the cancelled operation
  settings: undefined,
};
// simplest: raise via timeout option when the cause says deadline exceeded
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await page.goto(url);
} catch (e) {
  const s = String(e);
  if (/context deadline exceeded/.test(s)) {
    // real timeout: raise per-action timeout or waitUntil choice
    await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60_000 });
  } else if (/context canceled/.test(s)) {
    // aborted elsewhere: the suffix after ': ' names the cause (connection lost, teardown, ...)
    console.error('operation cancelled, cause:', s.split(': ').slice(1).join(': '));
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Any browser operation running on a context that gets cancelled: global timeout exceeded (K6_BROWSER_GLOBAL_TIMEOUT), iteration context cancelled at test end, or a connection-level cancelCtx cause such as 'connection closed with websocket code: 1006' or 'lost connection while closing the browser'.

Common situations: Users see this and fixate on 'context canceled' while the actionable detail is after the colon; typical sources are per-action timeouts too low (timeouts.default), test abort mid-navigation, or a browser crash whose real error was recorded as the cause.

Related errors


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