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 polling GET /cloud/v6/test_runs/{id} during --local-execution provisioning. The loop waits for status 'initializing' as the signal that k6 may begin local execution; if the backend reports 'completed' first, this k6 process can never attach to the run and the error is returned immediately.
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 93accf6570)
Solutions
- Check the Grafana Cloud UI for the run's status history to see who/what completed it
- Ensure only one k6 process provisions this load test at a time
- Start a fresh test run instead of reusing the previous testRunID
- If it recurs consistently, capture the status transitions via debug logging (k6 sets 'test status' Debug lines) and report a backend issue
Example fix
// before
if err := client.WaitForTestRunReady(ctx, testRunID, 0); err != nil {
return err
}
// after
if err := client.WaitForTestRunReady(ctx, testRunID, 0); err != nil {
if strings.Contains(err.Error(), "completed before k6 could start") {
// run already finished server-side; provision a new run
return provisionFreshRun(ctx)
}
return err
} Defensive patterns
Strategy: try-catch
Type guard
func isCompletedBeforeStart(err error) bool {
return err != nil && strings.Contains(err.Error(), "test run completed before k6 could start")
} Try / catch
err := client.WaitForTestRunReady(ctx, resp.TestRunID, pollInterval)
if err != nil {
if isCompletedBeforeStart(err) {
// terminal: provision a fresh run rather than retrying this one
}
return err
} Prevention
- Provision one run per k6 process; never share a testRunID across processes
- Check the run's status in the Grafana Cloud UI before retrying provisioning
- Log status transitions (the client already emits Debug lines) to catch state races early
When it happens
Trigger: ProvisionLocalExecution -> WaitForTestRunReady observes v6.StatusCompleted before v6.StatusInitializing. Happens when another executor already finished the run, when the same test run ID is re-used by a parallel process, or when a backend state race skips 'initializing' entirely.
Common situations: Duplicate/parallel k6 processes provisioning the same load test with the same token; retrying an old provisioning request that references a stale test run; backend-side automation that completed or force-completed the run between creation and the first poll.
Related errors
- wait for test run ready: %w
- fetching test status: %w
- notify test run completed: %w
- create or find load test: %w
- start local execution: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/c377a312c1c28033.
Report an issue: GitHub.