grafana/k6 · error

fetching test status

Error message

fetching test status: %w

What it means

Returned by Client.WaitForTestRunReady (internal/cloudapi/provisioning/api.go:144) when the underlying v6Client.FetchTest call fails while polling GET /cloud/v6/test_runs/{id}. A single failed poll aborts the whole wait — there is no retry around FetchTest at this layer — so even one transient failure (network blip, 401, 5xx) ends the wait-for-ready phase and the run stops before starting.

Solutions

  1. Inspect the wrapped error: 401/403 => token problem, 404 => test run gone, transport errors => network, context.Canceled => the run was interrupted locally.
  2. Re-run the test; if the queue wait is long and the network is flaky, that alone can trigger it.
  3. Verify the token still has access to the load test / project in the Grafana Cloud k6 UI.
  4. If you control the caller, wrap WaitForTestRunReady with a bounded retry loop so single-poll failures don't kill the run.
  5. Check status.k6.io / Grafana Cloud status page for API incidents during the wait window.

Example fix

// before
if err := c.WaitForTestRunReady(ctx, testRunID, pollInterval); err != nil { return err }

// after — tolerate transient poll failures without masking terminal ones
var err error
for attempt := 0; attempt < 3; attempt++ {
	err = c.WaitForTestRunReady(ctx, testRunID, pollInterval)
	if err == nil { break }
	var apiErr *cloudapi.APIError // adapt to the v6 client's typed error
	if errors.As(err, &apiErr) && (apiErr.Code == 404 || apiErr.Code == 401) {
		break // terminal — retrying cannot help
	}
	time.Sleep(time.Duration(attempt+1) * 2 * time.Second)
}
if err != nil { return err }
Defensive patterns

Strategy: retry

Try / catch

// Wrap the wait so a single failed poll doesn't kill a queued run.
err := c.WaitForTestRunReady(ctx, testRunID, poll)
if err != nil && !strings.Contains(err.Error(), "aborted before starting") &&
	!strings.Contains(err.Error(), "completed before") && !errors.Is(err, context.Canceled) {
	// transient poll failure — bounded backoff retry
	for i := 1; i <= 2 && err != nil; i++ {
		time.Sleep(time.Duration(i*3) * time.Second)
		err = c.WaitForTestRunReady(ctx, testRunID, poll)
	}
}

Prevention

When it happens

Trigger: Any FetchTest error inside the polling loop: expired/revoked API token mid-wait, test run deleted in the UI (404), network interruption, cloud API returning 4xx/5xx, or the parent context being cancelled (surfacing as ctx error inside the HTTP call).

Common situations: Long queue times on k6 Cloud with flaky connectivity; token permissions changed or token revoked while the test sat in queue; polling a test run someone deleted; strict egress firewalls dropping long-lived idle sessions.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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

Appendix: source

Thrown at internal/cloudapi/provisioning/api.go:144

// WaitForTestRunReady polls GET /cloud/v6/test_runs/{id} until the
// backend status becomes "initializing" (signalling that k6 can begin
// local execution). Returns an error if the test run reaches "aborted"
// or "completed" first. Cancellable via context. Logs status transitions
// at Debug level once per change.
//
// If pollInterval is <= 0 the defaultWaitPollInterval is used.
func (c *Client) WaitForTestRunReady(ctx context.Context, testRunID int64, pollInterval time.Duration) error {
	if pollInterval <= 0 {
		pollInterval = defaultWaitPollInterval
	}

	var lastStatus string

	for {
		progress, err := c.v6Client.FetchTest(ctx, testRunID)
		if err != nil {
			return fmt.Errorf("fetching test status: %w", err)
		}

		status := progress.Status.String()

		switch v6.Status(status) {
		case v6.StatusInitializing:
			return nil

		case v6.StatusAborted:
			var abortMsg string
			for _, e := range progress.StatusHistory {
				if e.Status == v6.StatusAborted && e.Message != "" {
					abortMsg = e.Message
					break
				}
			}
			if abortMsg != "" {
				return fmt.Errorf("test run aborted before starting: %s", abortMsg)

View on GitHub (pinned to 01ffac6f24)