grafana/k6 · error

test run completed before k6 could start

Error message

test run completed before k6 could start

What it means

Returned by Client.WaitForTestRunReady (internal/cloudapi/provisioning/api.go:167) when the polled test run reports status 'completed' before k6 ever saw 'initializing'. The state machine moved to a terminal finished state while the local k6 process was still waiting for its cue to start executing, so there is nothing left to drive: the backend considers the run done. This usually indicates a state race or configuration degenerate enough that the backend finished (or thought it finished) instantly.

Solutions

  1. Open the test run page for the ID being polled and check its timeline and results — if it genuinely ran, your local invocation lost the race to another one.
  2. Audit the script's executor config: every scenario needs a non-zero duration/VUs so the run has actual work.
  3. Make sure each invocation generates a fresh run (the client already mints a new idempotency key per StartLocalExecution call) — never reuse a previous request.
  4. If the run shows no work at all in the UI yet reports completed, report it with the run ID to k6 Cloud support.
Defensive patterns

Strategy: try-catch

Validate before calling

// Before starting, assert the script actually schedules work.
func hasRunnableWork(opts lib.Options) bool {
	for _, s := range opts.Scenarios {
		if s == nil {
			continue
		}
		if d := s.GetDuration(); d > 0 || s.GetVUs() > 0 {
			return true
		}
	}
	return false
}

Try / catch

if err := c.WaitForTestRunReady(ctx, testRunID, poll); err != nil {
	if strings.Contains(err.Error(), "completed before k6 could start") {
		// inspect the run page: either a state race or a degenerate zero-work config
		log.Warnf("run %d reported completed during wait; inspect its timeline", testRunID)
	}
	return err
}

Prevention

When it happens

Trigger: A test configuration the backend executes/finishes with zero local work (e.g. zero VUs or a zero/blank schedule slipping through); replaying a StartLocalExecution whose idempotency key collides with an already-completed run; backend state machine anomalies where 'completed' skips 'initializing'.

Common situations: Scripts with misconfigured executors producing empty schedules; retrying a start request after a network error where the first request actually succeeded and the run already finished; backend incidents flipping run states.

Related errors


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

Appendix: source

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

		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)
			}
			return fmt.Errorf("test run aborted before starting")

		case v6.StatusCompleted:
			return fmt.Errorf("test run completed before k6 could start")

		default:
			// created, queued, or any unrecognised state — keep polling.
			if status != lastStatus {
				c.logger.WithField("status", progress.FormatStatus()).Debug("test status")
				lastStatus = status
			}
		}

		select {
		case <-ctx.Done():
			return ctx.Err()
		case <-time.After(pollInterval):
			// continue polling
		}
	}
}

View on GitHub (pinned to 01ffac6f24)